Elasticsearch 5.4 嵌套字段versions的数量聚合问题求助
搞定Elasticsearch 5.4里嵌套字段
versions的聚合问题 兄弟,你踩的这个坑我之前也遇到过——问题出在Elasticsearch嵌套字段的特殊存储逻辑上!每个嵌套对象都会被当成独立的隐藏Lucene文档存起来,根文档本身根本没法直接用doc访问到versions字段,所以你加doc.containsKey('versions')时会一直返回false,结果全是0;去掉判断直接访问又会因为根文档里找不到这个字段报错。
给你两个靠谱的解决办法:
办法1:用nested聚合进入嵌套上下文(推荐,性能好)
先通过nested聚合钻进versions的上下文里,这样就能正常访问嵌套字段的数据了,再在里面做你需要的聚合。举个例子,如果你要统计所有versions的数量,或者对某个字段做聚合:
{ "aggs": { "get_nested_versions": { "nested": { "path": "versions" }, "aggs": { "version_total": { "value_count": { "script": { "inline": "1", // 这里换成你实际要处理的逻辑,比如访问versions里的具体字段 "lang": "painless" } } } } } } }
要是你需要聚合versions里的具体字段(比如version_code),把脚本改成doc['versions.version_code'].value就行,这样就能正确拿到嵌套字段的值。
办法2:直接读原始文档的_source(不推荐,慢)
如果实在没法用nested聚合,也可以直接访问原始文档的_source数据,但这种方式会加载整个文档,数据量大的时候性能拉胯,只适合小数据集:
{ "aggs": { "version_agg_result": { "sum": { "script": { "inline": "params._source.containsKey('versions') ? params._source.versions.size() : 0", "lang": "painless" } } } } }
这里通过params._source读取原始文档里的versions数组,判断存在后处理(比如取长度,或者你需要的其他聚合逻辑)。
最后提醒下:你的映射里必须明确把versions设成"type": "nested",不然Elasticsearch会把它当成普通对象,聚合逻辑也不对;另外Elasticsearch 5.4的Painless脚本语法和新版本有点不一样,别用高版本的API哦!
内容的提问来源于stack exchange,提问作者AJP
相关产品推荐
相关产品推荐

