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

如何用ElasticSearch实现移动端APP版本使用量统计及可视化?

移动端APP版本统计:ElasticSearch查询与可视化方案

我来帮你解决这个统计每个客户端最新版本并聚合计数的问题,结合你不想用update/upsert、只添加文档的需求,下面分两部分给出具体方案:

问题背景

你需要在ElasticSearch中存储移动端APP的初始化事件数据,统计每个客户端的最新版本并按版本分组计数(即安装量),现有数据示例如下:

  • clientId: ABC, clientVersion: 1.2.3, time: 2018-01-01
  • clientId: DEF, clientVersion: 1.2.3, time: 2018-01-02
  • clientId: GHI, clientVersion: 1.2.3, time: 2018-01-03
  • clientId: DEF, clientVersion: 1.2.3, time: 2018-01-04
  • clientId: GHI, clientVersion: 1.2.4, time: 2018-01-05

期望得到的统计结果是:

  • version 1.2.3: 2个安装量(ABC、DEF)
  • version 1.2.4: 1个安装量(GHI)

你尝试过用top_hits聚合按clientId去重,但发现无法在top_hits下添加子聚合来进一步统计版本,接下来看具体解决方案。

1. ElasticSearch 查询实现

我们可以用**scripted_metric聚合**来实现和你内存处理完全一致的逻辑:先跟踪每个客户端的最新版本,再按版本统计数量。这个聚合不需要依赖嵌套子聚合的限制,直接在分片和节点层面处理数据。

具体查询语句如下:

GET /metric/_search
{
  "size": 0, // 不需要返回原始文档,只看聚合结果
  "aggs": {
    "latest_version_installs": {
      "scripted_metric": {
        "init_script": "state.client_latest = [:]", // 初始化存储每个客户端的最新版本和时间
        "map_script": """
          def client_id = doc['clientId'].value;
          def current_time = doc['time'].value;
          def current_version = doc['clientVersion'].value;
          
          // 如果客户端不存在,或者当前文档时间更新,就更新最新版本
          if (!state.client_latest.containsKey(client_id) || current_time.isAfter(state.client_latest[client_id].time)) {
            state.client_latest[client_id] = ['time': current_time, 'version': current_version];
          }
        """,
        "combine_script": """
          // 分片内统计各版本的客户端数量
          def version_counts = [:];
          state.client_latest.values().each { entry ->
            def version = entry.version;
            version_counts[version] = (version_counts[version] ?: 0) + 1;
          }
          return version_counts;
        """,
        "reduce_script": """
          // 汇总所有分片的统计结果
          def final_counts = [:];
          states.each { shard_result ->
            shard_result.each { version, count ->
              final_counts[version] = (final_counts[version] ?: 0) + count;
            }
          }
          return final_counts;
        """
      }
    }
  }
}

执行这个查询后,你会在aggregations.latest_version_installs.value中得到期望的版本-安装量统计结果。

2. Kibana/Grafana 可视化实现

如果觉得写复杂的聚合脚本太麻烦,也可以直接在可视化工具中配置实现:

Kibana 实现步骤

  1. 创建数据视图:确保你的metric索引已经创建了包含clientId、clientVersion、time字段的数据视图。
  2. 创建过滤后的保存搜索:
    • 进入Discover页面,添加一个脚本过滤器:
      doc['time'].value == (max(time) over (partition by clientId))
      
      这个过滤器会只保留每个客户端的最新时间对应的文档。
    • 保存这个搜索,命名为「最新客户端版本」。
  3. 创建可视化图表:
    • 选择「条形图」或「饼图」类型,数据源选择刚才保存的「最新客户端版本」。
    • 在Metrics面板,选择「Unique Count」,字段选clientId(统计唯一客户端数)。
    • 在Buckets面板,添加「Terms」聚合,字段选clientVersion,按版本分组。
    • 调整图表样式,就能得到各版本的安装量可视化。

Grafana 实现步骤

  1. 配置ES数据源:确保已经连接到你的ElasticSearch集群,索引选择metric。
  2. 创建面板:
    • 选择「条形图」或「饼图」面板,进入Query配置:
      • Metric选择「Count」,然后添加两个Group by:
        1. 第一个Group by选「Terms」,字段clientVersion,用于按版本分组。
        2. 第二个Group by选「Filter」,添加脚本筛选:
          doc['time'].value == (max(time) over (partition by clientId))
          
    • 进入Transform配置,添加「Reduce」变换,选择「Unique Count」,字段选clientId,这样就会统计每个版本下的唯一客户端数。
    • 调整图表的显示设置,完成可视化配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:29