请求用于聚合数组子字段的Elasticsearch查询语句(含索引数据格式)
嘿,针对你这种带有嵌套对象数组的Elasticsearch索引聚合需求,我来给你梳理清晰的解决方案!
首先得提个关键前提:你的data字段必须在索引映射中定义为**nested类型**,不然Elasticsearch会把数组里的对象扁平化处理,聚合出来的结果会完全不符合预期。
第一步:确认/设置正确的索引映射
如果还没创建索引,或者需要调整已有映射(注意:已有数据的话需要重建索引重新导入),可以用下面的请求设置映射:
PUT /your_index_name { "mappings": { "properties": { "term": { "type": "keyword" }, "data": { "type": "nested", "properties": { "date": { "type": "date" }, "visits": { "type": "integer" }, "ranking": { "type": "integer" }, "orders": { "type": "integer" } } } } } }
第二步:常用聚合场景的查询示例
下面是几个你可能用到的聚合场景,直接改改索引名就能用:
场景1:按日期聚合,统计全量数据的总访问量、总订单数
比如想知道所有词条在各个日期的visits和orders总和:
GET /your_index_name/_search { "size": 0, // 不需要返回原始文档,只看聚合结果 "aggs": { "nested_data_scope": { "nested": { "path": "data" // 指定要操作的嵌套字段路径 }, "aggs": { "group_by_date": { "terms": { "field": "data.date", "order": { "_key": "asc" } // 按日期升序排列 }, "aggs": { "total_visits": { "sum": { "field": "data.visits" } }, "total_orders": { "sum": { "field": "data.orders" } } } } } } } }
场景2:先按词条分组,再按日期聚合统计细节
如果需要先把数据按term拆分,再看每个词条下不同日期的聚合数据(比如平均排名、总访问量):
GET /your_index_name/_search { "size": 0, "aggs": { "group_by_term": { "terms": { "field": "term", "size": 10 // 调整为你需要返回的词条数量 }, "aggs": { "nested_data_scope": { "nested": { "path": "data" }, "aggs": { "group_by_month": { "date_histogram": { "field": "data.date", "calendar_interval": "month" // 按月份聚合,也可以换成day/week/year }, "aggs": { "avg_ranking": { "avg": { "field": "data.ranking" } }, "sum_visits": { "sum": { "field": "data.visits" } } } } } } } } } }
场景3:筛选特定日期范围后再聚合
比如只想统计2018年1月到3月的数据,计算这段时间的总订单数和最高访问量:
GET /your_index_name/_search { "size": 0, "aggs": { "nested_data_scope": { "nested": { "path": "data" }, "aggs": { "filter_target_date_range": { "filter": { "range": { "data.date": { "gte": "2018-01-01", "lte": "2018-03-31" } } }, "aggs": { "total_orders": { "sum": { "field": "data.orders" } }, "max_visits": { "max": { "field": "data.visits" } } } } } } } }
核心注意事项
- 一定要用
nested聚合来包裹对data子字段的操作,否则Elasticsearch会把数组中所有visits、orders的值混在一起计算,得到错误的聚合结果。 - 如果你的索引已经存在且
data不是nested类型,无法直接修改字段类型,必须新建一个带正确映射的索引,然后把数据重新导入进去。
内容的提问来源于stack exchange,提问作者Kunal Kakade
相关产品推荐
相关产品推荐

