Elasticsearch聚合如何包含查询阶段_source的id与description字段
Elasticsearch聚合保留id、description及筛选嵌套数据的解决方法
核心思路
要同时保留文档的id/description字段,以及筛选指定locationId的嵌套locationData,需要结合**top_hits聚合**(获取原始文档字段)和嵌套聚合(筛选嵌套数据),或者直接用inner_hits(单文档场景更简便)。
场景1:多文档聚合场景(需分组保留字段)
假设你的数据结构如下:
{ "id": "doc_1", "description": "Sample document", "locationData": [ {"locationId": "loc_1", "name": "Location 1"}, {"locationId": "loc_2", "name": "Location 2"} ] }
可以用以下查询,先筛选目标文档,再通过聚合同时获取文档字段和匹配的嵌套数据:
{ "query": { "bool": { "filter": [ {"term": {"id.keyword": "doc_1"}}, // 按id筛选文档(id需为keyword类型) {"nested": { "path": "locationData", "query": {"term": {"locationData.locationId.keyword": "loc_1"}} // 筛选指定locationId的嵌套数据 }} ] } }, "aggs": { "group_by_document": { "terms": { "field": "id.keyword", "size": 10 // 根据文档数量调整 }, "aggs": { // 获取文档的id和description "document_info": { "top_hits": { "_source": ["id", "description"], "size": 1 // 每个文档仅返回1条结果 } }, // 筛选并获取匹配的locationData "filtered_location_data": { "nested": { "path": "locationData" }, "aggs": { "match_target_location": { "filter": { "term": {"locationData.locationId.keyword": "loc_1"} }, "aggs": { "location_details": { "top_hits": { "_source": ["locationData.*"], "size": 10 // 根据嵌套数据数量调整 } } } } } } } } } }
场景2:单文档查询场景(无需聚合更简便)
如果仅需查询单个文档,直接用inner_hits即可同时返回文档的id/description和匹配的嵌套数据,无需聚合:
{ "_source": ["id", "description"], // 指定返回的文档字段 "query": { "bool": { "filter": [ {"term": {"id.keyword": "doc_1"}}, {"nested": { "path": "locationData", "query": {"term": {"locationData.locationId.keyword": "loc_1"}}, "inner_hits": { // 返回匹配的嵌套数据 "_source": ["locationData.locationId", "locationData.name"], "size": 10 } }} ] } } }
关键注意事项
- 确保
id和locationData.locationId字段为keyword类型,否则term查询和terms聚合无法正常工作。 top_hits和inner_hits的size参数根据实际数据量调整,避免返回过多冗余结果。- 如果不需要分组,单文档场景优先用
inner_hits,比聚合更高效。
内容的提问来源于stack exchange,提问作者user19785518
相关产品推荐
相关产品推荐

