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

如何编写Elasticsearch子聚合查询统计先试用后注册的用户数量

实现方案

前提说明:你需要确保所有行为事件文档都携带@timestamp时间戳字段,用于判断事件发生的先后顺序,否则无法准确判断「先试用后注册」的逻辑,只能统计「既产生过免费试用行为又完成注册」的用户数。

修正后完整查询

{
  "size": 0, // 不返回原始文档,仅返回聚合结果节省资源
  "aggs": {
    "origin": {
      "terms": {
        "field": "origin.visitor_id.keyword", // 修正为实际的访客唯一标识字段
        "size": 10000 // 可根据实际用户量调整,数据量过大建议用partition参数分页遍历
      },
      "aggs": {
        // 聚合1:判断该用户最早的行为是否属于免费试用层级
        "user_started_out_free": {
          "scripted_metric": {
            "init_script": "state.min_time = Long.MAX_VALUE; state.is_free = false",
            "map_script": """
              long current_time = doc['@timestamp'].value.toInstant().toEpochMilli();
              if (current_time < state.min_time) {
                state.min_time = current_time;
                state.is_free = doc['user.tenant_tier.keyword'].value == 'free';
              }
            """,
            "combine_script": "return state.is_free ? 1 : 0",
            "reduce_script": "return states[0]"
          }
        },
        // 聚合2:判断该用户是否存在注册成功事件
        "then_registered": {
          "filter": {
            "term": {
              "event_key.keyword": "registration" // 对应你的事件标识字段
            }
          }
        },
        // 聚合3:判断是否同时满足「先试用后注册」条件
        "is_trial_user_then_registered": {
          "bucket_script": {
            "buckets_path": {
              "user_started_out_free": "user_started_out_free.value",
              "registered_count": "then_registered._count"
            },
            "script": "params.user_started_out_free == 1 && params.registered_count > 0 ? 1 : 0"
          }
        }
      }
    },
    // 最终统计符合条件的用户总数
    "num_trial_then_registered": {
      "sum_bucket": {
        "buckets_path": "origin>is_trial_user_then_registered"
      }
    }
  }
}

关键逻辑说明

  • user_started_out_free 脚本指标聚合:遍历同一个访客的所有事件,记录最早发生事件对应的租户层级,若为free则返回1,否则返回0
  • then_registered 过滤聚合:统计同一个访客下注册事件的数量,大于0代表该访客完成过注册
  • is_trial_user_then_registered 桶脚本聚合:同时满足「最早事件为免费层级」和「存在注册事件」则返回1,否则返回0
  • 最终的num_trial_then_registered 求和聚合:累加所有符合条件的访客数,就是目标统计结果

注意事项

  • 如果你的ES版本较低不支持三引号多行脚本,可把脚本内容压缩为单行,转义特殊字符即可
  • 如果访客量超过10万,不要直接把terms的size设置为过大值,建议使用terms聚合的partition参数分批遍历所有访客,避免节点内存溢出
  • 如果确实没有时间戳字段不需要判断顺序,可以把user_started_out_free替换为过滤user.tenant_tier.keyword = free的filter聚合,判断doc_count>0即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:54:03