如何在Kibana中将单条记录计入多个聚合统计项
Elasticsearch组件拆分统计问题
日志结构
应用日志存储在Elasticsearch中,包含以下字段:
@timestamp: Oct 24, 2023 @ 20:15:52.043 Action: INSTALL Components: a; b UserName: U12345
需求
按单个组件分组,统计每个组件的安装次数,以及执行这些安装操作的唯一用户数。
当前问题
直接基于原始Components字段做分组聚合时,得到的是组件组合(如a;b)的统计结果,无法将单条记录按包含的组件拆分后分别计入统计:
当前查询结果:
{ "key" : "a;b", "doc_count" : 10, "unique_user_ids" : { "value" : 2 } }, { "key" : "a;c", "doc_count" : 8, "unique_user_ids" : { "value" : 1 } },
期望结果
需要将每个组件单独拆分统计,比如包含a的两条记录会累计a的安装次数,同时合并唯一用户数:
{ "key" : "a", "doc_count" : 18, "unique_user_ids" : { "value" : 3 } }, { "key" : "b", "doc_count" : 10, "unique_user_ids" : { "value" : 2 } }, { "key" : "c", "doc_count" : 8, "unique_user_ids" : { "value" : 1 } },
解决方案
方案1:脚本聚合直接拆分
无需修改索引结构,使用脚本在聚合时拆分Components字段:
{ "size": 0, "query": { "term": { "Action": "INSTALL" } }, "aggs": { "components": { "terms": { "script": { "source": "doc['Components.keyword'].value.split('; ')" }, "size": 100 }, "aggs": { "unique_user_ids": { "cardinality": { "field": "UserName.keyword" } } } } } }
- 脚本通过
split('; ')把Components的字符串值拆分成单个组件的数组 terms聚合会自动遍历数组中的每个组件,将其作为独立key统计安装次数(doc_count)cardinality聚合统计每个组件对应的唯一用户数
方案2:创建运行时字段(推荐,性能更优)
如果需要多次执行这类查询,可以先创建一个运行时字段,提前把Components拆分成数组:
PUT /your_index/_settings { "index": { "runtime": { "component_list": { "type": "keyword", "script": "emit(doc['Components.keyword'].value.split('; '))" } } } }
之后直接基于这个运行时字段做聚合查询:
{ "size": 0, "query": { "term": { "Action": "INSTALL" } }, "aggs": { "components": { "terms": { "field": "component_list", "size": 100 }, "aggs": { "unique_user_ids": { "cardinality": { "field": "UserName.keyword" } } } } } }
内容的提问来源于stack exchange,提问作者alko
相关产品推荐
相关产品推荐

