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

Elasticsearch能否基于子聚合结果过滤聚合?

基于子聚合结果过滤Elasticsearch聚合的实现方案

需求背景

在交易索引中,我们需要筛选出总余额非零的账户(总余额=贷方总和-借方总和),希望直接在Elasticsearch查询阶段完成过滤,避免客户端遍历所有聚合结果再做筛选。

交易数据的_source结构示例:

"_source": {
  "debit": 50,
  "account_id": "account-id-1"
}

"_source": {
  "credit": 50,
  "account_id": "account-id-1"
}

"_source": {
  "debit": 25,
  "account_id": "account-id-2"
}

"_source": {
  "credit": 50,
  "account_id": "account-id-2"
}

方案一:保留借贷明细,过滤余额为零的账户

通过bucket_selector聚合,可以基于子聚合的结果对父terms聚合的bucket进行过滤。在原有聚合基础上,添加一个bucket_selector判断sum_credit和sum_debit是否相等,直接排除余额为零的账户bucket。

最终查询DSL

{
  "size": 0,
  "aggs": {
    "terms_account_id": {
      "terms": {
        "field": "account_id"
      },
      "aggs": {
        "sum_debit": {
          "sum": {
            "field": "debit"
          }
        },
        "sum_credit": {
          "sum": {
            "field": "credit"
          }
        },
        "filter_non_zero_balance": {
          "bucket_selector": {
            "buckets_path": {
              "debitTotal": "sum_debit",
              "creditTotal": "sum_credit"
            },
            "script": "params.debitTotal != params.creditTotal"
          }
        }
      }
    }
  }
}

返回结果

"aggregations": {
    "terms_account_id": {
      "buckets": [
        {
          "key": "account-id-2",
          "sum_credit": { "value": 50 },
          "sum_debit": { "value": 25 }
        }
      ]
    }
  }

方案二:直接计算总余额并过滤

如果只需要总余额结果,可以先通过bucket_script计算出账户的总余额(贷方总和-借方总和),再用bucket_selector过滤掉余额为0的账户。

最终查询DSL

{
  "size": 0,
  "aggs": {
    "terms_account_id": {
      "terms": {
        "field": "account_id"
      },
      "aggs": {
        "sum_debit": {
          "sum": {
            "field": "debit"
          }
        },
        "sum_credit": {
          "sum": {
            "field": "credit"
          }
        },
        "sum_total": {
          "bucket_script": {
            "buckets_path": {
              "debit": "sum_debit",
              "credit": "sum_credit"
            },
            "script": "params.credit - params.debit"
          }
        },
        "filter_non_zero_balance": {
          "bucket_selector": {
            "buckets_path": {
              "total": "sum_total"
            },
            "script": "params.total != 0"
          }
        }
      }
    }
  }
}

返回结果

"aggregations": {
    "terms_account_id": {
      "buckets": [
        {
          "key": "account-id-2",
          "sum_total": { "value": 25 }
        }
      ]
    }
  }

关键说明

bucket_selector是实现基于子聚合结果过滤的核心,它允许引用子聚合的计算值,通过脚本逻辑筛选符合条件的bucket,完全在Elasticsearch服务端完成过滤,减少了客户端的数据传输和处理开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:13