如果你写painless脚本的时候,发现对不同结构的字段获取有点困惑,那么本文可能会帮助你。
取普通字段
默认ES会把非text、非nested的字段存到doc values列存储中,方便单独获取,而不用取_source里取,这样IO性能就很好。
假设你有一个字段:”a”: 1。
那么doc[‘a’]返回的是[1],是一个数组。
doc[‘a’].value返回的是1,也就是取第一个元素。
doc[‘a’].values与doc[‘a’]表现一致,返回[1]。
特殊一点的是object类型的字段,ES底层存储时是key扁平化的,所以你应该直接这样取:
doc[‘xxx.yyy’]
doc[‘xxx.yyy’].value
doc[‘xxx.yyy’].values
取非普通字段
主要指nested字段和text字段,它们不会进入doc values。
解决方法优先采用store: true属性,强制它们进入列存储中独立保存,这样获取的时候IO性能就好得多,但是性能没有doc values好。
获取store字段的方法和普通字段没有区别,仍旧走doc变量。
但是nested字段走store后,获取方式肯定不是doc[‘xxx.yyy’],而是遍历doc[‘xxx’].values数组,每个子doc再获取yyy(我没试验,大家可以试试)。
取_source
其实_source也是一个store存储,包含了整个你索引的json文档。
只是_source太大了,远不如把单个列独立store起来的性能好,所以最次的方法就是走_source。
在修改操作时需要_ctx._source获取,在查询操作时需要params._source获取,上下文不同写法不同。
其他
doc values取到的数据类型,一定是与mapping一致的,经过约束转换的。
而走store和_source取到的数据类型,则是你索引时原样放入的数据类型,比如mapping是一个int字段,你索引时设置了一个”123″,其实doc values会存123,然而_source和store中仍旧是”123″,所以写painless脚本就会遇到一个类型问题,需要先判断是不是字符串”123″(用def+instanceof判断),如果是还得转换成整形才能运算,是很头疼的。
如果文章帮助了你,请帮我点击1次谷歌广告,或者微信赞助1元钱,感谢!
知识星球有更多干货内容,对我认可欢迎加入:
理解Elasticsearch Painless脚本中字段的获取与存储
本文介绍了如何在Elasticsearch的Painless脚本中处理不同类型的字段,如普通字段、object类型、nested字段和text字段。docvalues提供高效的IO性能,但text和nested字段不被存储。通过设置store属性,可以将这些字段独立存储,提高查询性能。对于nested字段,需要遍历doc.values来获取。同时,_source虽然包含所有文档信息,但其性能较低。在处理数据类型时,需要注意docvalues与_store、_source之间的差异,可能需要类型转换。
1475

被折叠的 条评论
为什么被折叠?



