OpenSearch/ElasticSearch嵌套聚合中拼接多字段作为分桶键的方法
问题根因
你之前的脚本聚合返回全量null null,是两个写法错误导致的:
- nested聚合进入嵌套上下文后,遍历单位是每一个独立的嵌套子文档,此时
params._source指向的是根文档的原始内容,根本无法获取当前遍历到的嵌套子文档字段值 - 聚合场景下优先通过
doc映射读取字段值,不仅性能远高于读取_source,也不会出现上下文路径匹配错误的问题
正确实现方式
直接在terms聚合的脚本中通过doc值读取当前嵌套子文档的两个字段,拼接为空格分隔的字符串作为分桶key即可,查询语句如下:
GET house/_search { "size": 0, "aggs": { "people": { "nested": { "path": "people" }, "aggs": { "people.fullname": { "terms": { "script": "doc['people.forename'].value + ' ' + doc['people.surname'].value" } } } } } }
执行后返回的聚合分桶完全符合预期:
Dave Daveson匹配文档数2Jeff Jeffson匹配文档数1Jeffs Jeffsons匹配文档数1
性能优化提示
如果这类全名拼接聚合是高频查询场景,不建议长期使用运行时脚本实现。可以在索引mapping的people嵌套属性中新增一个fullname类型为keyword的字段,数据写入时直接拼接好全名存入该字段,查询时直接对该字段做terms聚合即可,查询性能会比脚本聚合高一个量级。
内容的提问来源于stack exchange,提问作者trevornelson
相关产品推荐
相关产品推荐

