如何对Elasticsearch的嵌套与非嵌套字段执行matrix_stats聚合?
实现方案
要对非嵌套字段score和嵌套列表中id=4的value字段执行matrix_stats聚合,核心是把嵌套字段的目标值关联到父文档层面,以下两种方法可以实现:
方法一:通过Runtime字段提取目标值
在查询时定义一个Runtime字段,提前从嵌套的list中提取出id=4对应的value,之后直接在matrix_stats聚合中使用这个字段和score字段。
示例DSL:
GET /your_index/_search { "size": 0, "runtime_mappings": { "list_value_id4": { "type": "double", "script": { "source": """ def targetVal = null; // 遍历嵌套的id数组,匹配id=4的条目 for (int i = 0; i < doc['list.id'].length; i++) { if (doc['list.id'][i] == 4) { targetVal = doc['list.value'][i]; break; // 找到第一个匹配的就停止 } } emit(targetVal); """ } } }, "aggs": { "matrix_stats_analysis": { "matrix_stats": { "fields": ["score", "list_value_id4"] } } } }
方法二:直接在matrix_stats聚合中使用脚本字段
无需提前定义Runtime字段,直接在matrix_stats的fields里通过脚本分别指定两个字段的取值逻辑。
示例DSL:
GET /your_index/_search { "size": 0, "aggs": { "matrix_stats_analysis": { "matrix_stats": { "fields": [ { "name": "score", "script": "doc['score'].value" }, { "name": "list_value_id4", "script": """ def targetVal = null; for (int i = 0; i < doc['list.id'].length; i++) { if (doc['list.id'][i] == 4) { targetVal = doc['list.value'][i]; break; } } return targetVal; """ } ] } } } }
注意事项
- 如果同一文档的
list中有多个id=4的条目,上述脚本会取第一个匹配的value,可根据需求修改逻辑(比如取平均值、总和等)。 - 确保
list字段在索引中是嵌套类型,否则数组的id和value会被扁平化,导致脚本匹配出错。
内容的提问来源于stack exchange,提问作者Sakthi Prasath M
相关产品推荐
相关产品推荐

