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

Elasticsearch统计Top5接口时如何正则替换URL用户ID合并统计

方案1:查询时实时处理(无需修改现有索引,适合临时统计场景)

你可以在聚合时新增runtime字段,用Painless脚本对原始URL做清洗,替换掉用户ID段为*之后再做聚合,修改后的查询DSL如下:

{
  "runtime_mappings": {
    "cleaned_url": {
      "type": "keyword",
      "script": {
        "source": """
          // 匹配用户ID的正则:纯字母/纯数字/字母数字混合,长度≥8(可根据实际ID长度调整)
          def idPattern = /^[a-zA-Z0-9]{8,}$/;
          def urlParts = doc['data.url.keyword'].value.splitOnToken('/');
          def cleanedParts = new ArrayList();
          for (def part : urlParts) {
            if (part == '') continue;
            // 匹配到用户ID特征就替换为*
            if (idPattern.matcher(part).matches()) {
              cleanedParts.add('*');
            } else {
              cleanedParts.add(part);
            }
          }
          emit('/' + String.join('/', cleanedParts));
        """
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "@timestamp": {
              "from": "now-15m",
              "to": "now",
              "include_lower": true,
              "include_upper": true,
              "boost": 1
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "aggregations": {
    "Url": {
      "terms": {
        "field": "cleaned_url", // 改为聚合清洗后的URL字段
        "size": 5,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "Status": {
          "terms": {
            "field": "data.response.status",
            "size": 5,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    }
  }
}
  • 可根据你实际的用户ID长度、特征调整正则规则,避免误替换正常的接口路径段。

方案2:写入时预处理(性能更高,适合长期高频统计场景)

如果这类统计是高频需求,建议在数据写入Elasticsearch时就通过Ingest Pipeline做预处理,把清洗后的路径存为独立的keyword字段,后续直接聚合该字段即可,避免每次查询都做实时计算消耗性能。
预处理Pipeline示例:

PUT _ingest/pipeline/clean_url_pipeline
{
  "processors": [
    {
      "script": {
        "source": """
          def idPattern = /^[a-zA-Z0-9]{8,}$/;
          def urlParts = ctx.data.url.splitOnToken('/');
          def cleanedParts = new ArrayList();
          for (def part : urlParts) {
            if (part == '') continue;
            if (idPattern.matcher(part).matches()) {
              cleanedParts.add('*');
            } else {
              cleanedParts.add(part);
            }
          }
          ctx.data.clean_url = '/' + String.join('/', cleanedParts);
        """
      }
    }
  ]
}

配置Pipeline生效后,后续写入的文档都会新增data.clean_url字段,你可以直接用该字段做聚合,查询性能会比方案1高很多。


结果格式适配

聚合返回后,你只需要遍历Url聚合的buckets,把每个bucket的key和下属Status聚合的结果拼接即可得到你期望的*/payment 200:2格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 15:36:03