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

Elasticsearch 数组字段范围过滤后按用户分组count聚合如何实现?

Elasticsearch 数组字段区间过滤计数聚合方案

核心实现思路

  • 先通过terms聚合按customer_id字段对所有文档分组,保证所有用户都出现在统计结果中
  • 嵌套sum聚合配合自定义Painless脚本,遍历每个文档的purchase_date_list数组,累加符合20210101到当前日期区间的元素个数,最终得到每个用户的有效购买次数

完整查询DSL

假设你的索引中purchase_date_list存储的是yyyyMMdd格式的整数,查询语句如下:

GET 替换为你的实际索引名/_search
{
  "size": 0,
  "aggs": {
    "按用户分组": {
      "terms": {
        "field": "customer_id",
        "size": 1000
      },
      "aggs": {
        "2021年至今购买次数": {
          "sum": {
            "script": {
              "source": """
                int count = 0;
                def nowDate = new SimpleDateFormat("yyyyMMdd").format(new Date()) as int;
                for (def purchaseDate : doc['purchase_date_list']) {
                  if (purchaseDate >= 20210101 && purchaseDate <= nowDate) {
                    count++;
                  }
                }
                return count;
              """,
              "lang": "painless"
            }
          }
        }
      }
    }
  }
}

如果担心服务端时区和预期不一致,也可以把日期区间作为参数传入,避免脚本自动生成日期的误差:

GET 替换为你的实际索引名/_search
{
  "size": 0,
  "aggs": {
    "按用户分组": {
      "terms": {
        "field": "customer_id",
        "size": 1000
      },
      "aggs": {
        "2021年至今购买次数": {
          "sum": {
            "script": {
              "source": """
                int count = 0;
                for (def purchaseDate : doc['purchase_date_list']) {
                  if (purchaseDate >= params.startDate && purchaseDate <= params.endDate) {
                    count++;
                  }
                }
                return count;
              """,
              "params": {
                "startDate": 20210101,
                "endDate": 20240520 // 替换为你需要的截止日期
              }
            }
          }
        }
      }
    }
  }
}

结果说明

返回结果的aggregations.按用户分组.buckets列表中,每个项的key为customer_id,2021年至今购买次数.value就是对应用户的统计值,和预期结果完全匹配:用户1返回2,用户2返回0,用户3返回1。

注意事项

  • 如果purchase_date_list是日期类型,只需要修改脚本中的判断逻辑,直接用日期对象的isAfter/isBefore方法判断即可
  • terms聚合的size参数需要根据你的用户总数调整,避免漏掉用户
  • 需要确保customer_id、purchase_date_list字段开启了doc_values(默认配置已开启,支持聚合运算)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:54:05