基于子文档聚合结果筛选ES父文档的查询方案问询(ES7.3)
解决ES 7.3父子文档聚合筛选父文档的问题
我来帮你搞定这个需求!在Elasticsearch 7.3里,要筛选出近7天内子文档page_view_count总和大于25的父文档,我们可以通过聚合+管道筛选+关联父文档的方式来实现,这是最直接高效的方案,下面是具体的实现步骤和代码:
完整查询语句
POST example/_search { "size": 0, "query": { "bool": { "filter": [ // 筛选近7天的子文档 { "range": { "creation_date": { "gte": "now-7d/d", "lt": "now/d" } } }, // 指定只处理session类型的子文档 { "term": { "join.name": "session" } } ] } }, "aggs": { // 按父文档ID分组,把同一个用户的子文档归为一组 "group_by_parent": { "terms": { "field": "join.parent", "size": 10000 // 这里设置足够大的数值,确保覆盖所有符合条件的父文档 }, "aggs": { // 计算每组子文档的page_view_count总和 "total_page_views": { "sum": { "field": "page_view_count" } }, // 管道聚合:只保留总和大于25的父文档分组 "filter_high_total": { "bucket_selector": { "buckets_path": { "total": "total_page_views" }, "script": "params.total > 25" } }, // 获取符合条件的父文档详情 "parent_document": { "top_hits": { "size": 1, "_source": ["type", "device", "profileId", "updatedAt"], // 指定要返回的父文档字段 "query": { "term": { "_id": "{{key}}" // 用分组的key(父文档ID)匹配父文档 } } } } } } } }
关键部分解释
- 前置过滤子文档:首先通过
bool查询筛选出近7天内的session类型子文档,这样我们只处理有效数据,减少不必要的计算开销。 - 按父ID分组:使用
terms聚合基于join.parent字段(存储父文档ID)分组,把同一个用户的所有会话子文档归到一起。 - 计算总和并筛选:先用
sum聚合统计每组的浏览量总和,再通过bucket_selector管道聚合过滤掉总和≤25的分组,只保留符合条件的父文档组。 - 获取父文档数据:最后用
top_hits聚合,通过分组的key(父文档ID)精准查询对应的父文档,返回你需要的字段内容。
注意事项
size: 0:因为我们不需要返回原始的子文档,只关心聚合结果中的父文档数据,所以设置为0可以节省带宽。terms.size:如果你的符合条件的父文档数量很多,要把这个值设置得足够大;如果数据量超大,建议改用composite聚合来实现分页查询。- 版本兼容性:这个方案完全适配ES 7.3版本,所有用到的聚合和管道功能在该版本中都是支持的。
内容的提问来源于stack exchange,提问作者Yash Tandon
相关产品推荐
相关产品推荐

