如何在Elasticsearch的Composite聚合中排除指定parameter_code?
最近我在使用Elasticsearch的Composite聚合做分组统计时遇到了个问题:我需要在聚合结果里排除某些指定的parameter_code值,试了好几种方式都没成功,想请教下怎么解决?
先给大家看下我的索引里的示例文档:
{ "end_date": 1230314400000, "parameter_codes": [28, 35, 30], "platform_code": "41012", "start_date": 1230314400000, "station_id": 7833246 }
我当前的搜索请求是用来获取每个platform_code/parameter_codes组合的结果,同时关联对应的station_id,还做了bucket分页:
{ "size": 0, "query": { "match_all": { "boost": 1.0 } }, "_source": false, "aggregations": { "compositeAgg": { "composite": { "size": 10, "sources": [ { "platform_code": { "terms": { "field": "platform_code", "missing_bucket": false, "order": "asc" } } }, { "parameter_codes": { "terms": { "field": "parameter_codes", "missing_bucket": false, "order": "asc" } } } ] }, "aggregations": { "aggstation_id": { "terms": { "field": "station_id", "size": 2147483647, "min_doc_count": 1, "shard_min_doc_count": 0, "show_term_doc_count_error": false, "order": { "_key": "asc" } } }, "pipe": { "bucket_sort": { "sort": [ { "_key": { "order": "asc" } } ], "from": 0, "size": 10, "gap_policy": "SKIP" } } } } } }
这个请求能正常返回结果,但现在我需要排除parameter_codes=35的组合,只保留{"platform_code": "41012", "parameter_codes": 28}和{"platform_code": "41012", "parameter_codes": 30}这两个bucket。
解决方案一:在查询阶段过滤掉不需要的参数值
这种方法最简单直接,通过在query中添加must_not的terms查询,直接过滤掉包含要排除的parameter_codes的文档,这样聚合时自然不会出现对应的bucket。修改后的请求如下:
{ "size": 0, "query": { "bool": { "must": [ { "match_all": { "boost": 1.0 } } ], "must_not": [ { "terms": { "parameter_codes": [35] } } ] } }, "_source": false, "aggregations": { "compositeAgg": { "composite": { "size": 10, "sources": [ { "platform_code": { "terms": { "field": "platform_code", "missing_bucket": false, "order": "asc" } } }, { "parameter_codes": { "terms": { "field": "parameter_codes", "missing_bucket": false, "order": "asc" } } } ] }, "aggregations": { "aggstation_id": { "terms": { "field": "station_id", "size": 2147483647, "min_doc_count": 1, "shard_min_doc_count": 0, "show_term_doc_count_error": false, "order": { "_key": "asc" } } }, "pipe": { "bucket_sort": { "sort": [ { "_key": { "order": "asc" } } ], "from": 0, "size": 10, "gap_policy": "SKIP" } } } } } }
如果需要排除多个值,只需要在must_not的terms数组里添加更多数值即可,比如[35,60]。
解决方案二:在Composite聚合的terms源中直接排除指定值
如果你不想过滤整个查询结果(比如其他聚合逻辑还需要用到包含这些参数的文档),可以直接在Composite聚合的parameter_codes的terms配置里添加exclude参数,仅在这个聚合维度里排除指定值。修改后的聚合部分如下:
{ "size": 0, "query": { "match_all": { "boost": 1.0 } }, "_source": false, "aggregations": { "compositeAgg": { "composite": { "size": 10, "sources": [ { "platform_code": { "terms": { "field": "platform_code", "missing_bucket": false, "order": "asc" } } }, { "parameter_codes": { "terms": { "field": "parameter_codes", "missing_bucket": false, "order": "asc", "exclude": [35] } } } ] }, "aggregations": { "aggstation_id": { "terms": { "field": "station_id", "size": 2147483647, "min_doc_count": 1, "shard_min_doc_count": 0, "show_term_doc_count_error": false, "order": { "_key": "asc" } } }, "pipe": { "bucket_sort": { "sort": [ { "_key": { "order": "asc" } } ], "from": 0, "size": 10, "gap_policy": "SKIP" } } } } } }
这种方式只会影响Composite聚合的parameter_codes维度,不会改变整个查询的结果集,适合需要保留原始数据范围但仅在该聚合中排除特定值的场景。
执行修改后的请求后,就能得到你想要的仅包含指定parameter_codes的聚合结果了。
内容的提问来源于stack exchange,提问作者Guilhem.Legal

