如何在ElasticSearch中按日志片段分组统计用户请求量?
按用户ID统计特定API请求次数的ElasticSearch查询方案
要实现统计访问/api/v1/person端点次数最多的10位用户,需要结合查询过滤和terms聚合完成,以下是具体配置:
一、结构化日志场景(已提取用户ID字段)
如果日志已结构化(比如用户ID单独存在user_id字段,日志内容存在message字段),使用以下查询:
GET _search { "size": 0, // 无需返回原始日志文档,仅获取聚合结果 "query": { "match": { "message": "API request: [GET] /api/v1/person" // 过滤目标API的请求日志 } }, "aggs": { "top_users": { "terms": { "field": "user_id.keyword", // 必须用keyword类型字段做精确聚合 "size": 10, // 返回请求量Top10的用户 "order": { "_count": "desc" // 按请求次数降序排列 } } } } }
二、非结构化日志场景(需从文本提取用户ID)
如果日志未结构化,没有单独的用户ID字段,可通过Painless脚本从日志文本中提取用户ID:
GET _search { "size": 0, "query": { "match": { "message": "API request: [GET] /api/v1/person" } }, "aggs": { "top_users": { "terms": { "script": { "source": """ def logContent = doc['message'].value; def userIdStart = logContent.indexOf('from user: ') + 10; return logContent.substring(userIdStart); """, "lang": "painless" }, "size": 10, "order": { "_count": "desc" } } } } }
结果提取
执行查询后,从ElasticSearch返回的JSON结果中,aggregations.top_users.buckets节点包含所需数据:
key对应用户IDdoc_count对应该用户的请求次数
将这些数据整理后即可得到你期望的CSV格式统计结果。
注意事项
- 字段替换:请根据实际日志存储的字段名,替换示例中的
message和user_id字段。 - Keyword类型:聚合用户ID时必须使用keyword类型字段,否则分词会导致聚合结果错误;如果没有对应keyword字段,需先更新索引映射,或使用脚本提取方式。
内容的提问来源于stack exchange,提问作者Jake Chambers
相关产品推荐
相关产品推荐

