如何实现带包含排除条件的Unique conditional count统计
带包含排除条件的唯一分组计数实现
需求说明:按groupId字段分组统计,仅保留分组内存在place等于london的记录且不存在place等于paris的记录的分组,每个符合条件的分组计数为1。
示例文档
[ { "groupId": 123, "place": "london" }, { "groupId": 123, "place": "berlin" }, { "groupId": 456, "place": "london" }, { "groupId": 789, "place": "london" }, { "groupId": 789, "place": "paris" }, { "groupId": 789, "place": "berlin" }, { "groupId": "ABC", "place": "tokyo" } ]
期望输出
[ { "groupId": 123, "count": "1" }, { "groupId": 456, "count": "1" } ]
实现方案(Elasticsearch DSL)
通过多阶段聚合完成筛选和计数:
- 按
groupId分组 - 每个分组内统计是否包含
london和paris的记录 - 筛选出符合条件的分组
- 为每个有效分组生成计数
{ "size": 0, "aggs": { "group_by_id": { "terms": { "field": "groupId", "size": 1000 }, "aggs": { "place_filters": { "filters": { "filters": { "has_london": {"term": {"place": "london"}}, "has_paris": {"term": {"place": "paris"}} } } }, "filter_valid_groups": { "bucket_selector": { "buckets_path": { "london_count": "place_filters>has_london>doc_count", "paris_count": "place_filters>has_paris>doc_count" }, "script": "params.london_count > 0 && params.paris_count == 0" } }, "set_count": { "bucket_script": { "buckets_path": {}, "script": "1" } } } } } }
结果说明
执行上述查询后,聚合结果中的group_by_id.buckets会包含所有符合条件的分组,每个分组的set_count.value即为1。如果需要完全匹配期望的输出格式,可以对聚合结果做简单的格式转换,提取key(即groupId)和set_count.value(即count)。
内容的提问来源于stack exchange,提问作者FredShevek
相关产品推荐
相关产品推荐

