You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤Elasticsearch聚合结果中双字段为null的Buckets

过滤Elasticsearch聚合中subject和login均为null的桶

问题场景

当前查询会返回包含subject和login字段均为null的聚合桶,需求是从聚合结果中排除这类桶。原查询及返回的聚合结果如下:

原查询语句

{
  "bool": {
    "must": [
      {
        "bool": {
          "should": [
            {
              "terms": {
                "username.d": [
                  "abc.com"
                ],
                "boost": 1
              }
            },
            {
              "terms": {
                "authorization_service.d": [
                  "gmail.com"
                ],
                "boost": 1
              }
            }
          ],
          "must_not": [
            {
              "exists": {
                "field": "username.email"
              }
            },
            {
              "exists": {
                "field": "username.login"
              }
            }
          ],
          "boost": 1
        }
      },
      {
        "exists": {
          "field": "password.hash",
          "boost": 1
        }
      }
    ],
    "adjust_pure_negative": true,
    "boost": 1
  }
}

原聚合结果示例

"aggregations": {
    "subjects": {
      "after_key": {
        "subject": null,
        "login": null,
        "authorization_service": "abc.com"
      },
      "buckets": [
        {
          "key": {
            "subject": null,
            "login": null,
            "authorization_service": "abc.com"
          },
          "doc_count": 10
        }
      ]
    }
  }

解决思路

可以通过查询阶段过滤或聚合阶段过滤两种方式实现需求,以下是具体方案:

方案一:查询阶段过滤(推荐,更高效)

在原查询的must_not中添加条件,直接排除subject和login均为null的文档,从源头上避免生成这类聚合桶。

修改后的查询语句:

{
  "bool": {
    "must": [
      {
        "bool": {
          "should": [
            {
              "terms": {
                "username.d": [
                  "abc.com"
                ],
                "boost": 1
              }
            },
            {
              "terms": {
                "authorization_service.d": [
                  "gmail.com"
                ],
                "boost": 1
              }
            }
          ],
          "must_not": [
            {
              "exists": {
                "field": "username.email"
              }
            },
            {
              "exists": {
                "field": "username.login"
              }
            },
            // 新增:排除subject和login均为null的文档
            {
              "bool": {
                "must": [
                  {"match": {"subject": null}},
                  {"match": {"login": null}}
                ]
              }
            }
          ],
          "boost": 1
        }
      },
      {
        "exists": {
          "field": "password.hash",
          "boost": 1
        }
      }
    ],
    "adjust_pure_negative": true,
    "boost": 1
  }
}

方案二:聚合阶段过滤(灵活,适合无法修改主查询的场景)

使用bucket_selector聚合,在聚合结果生成后过滤掉subject和login均为null的桶(要求Elasticsearch版本2.0及以上)。

示例聚合语句(需结合原查询使用):

{
  "aggs": {
    "subjects": {
      "composite": {
        "sources": [
          {"subject": {"terms": {"field": "subject"}}},
          {"login": {"terms": {"field": "login"}}},
          {"authorization_service": {"terms": {"field": "authorization_service.d"}}}
        ]
      },
      "aggs": {
        "filter_invalid_buckets": {
          "bucket_selector": {
            "buckets_path": {
              "subjectKey": "_key.subject",
              "loginKey": "_key.login"
            },
            "script": "params.subjectKey != null || params.loginKey != null"
          }
        }
      }
    }
  }
}

该脚本会保留subject或login至少有一个不为null的桶,直接过滤掉两者均为null的桶。


内容的提问来源于stack exchange,提问作者NQScalar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:15:37