KQL查询中如何按operation_id分组聚合dynamic类型列
解决方案
你之前的写法问题在于summarize by后同时指定operation_id和details字段,会按照两个字段的唯一值组合分组,自然每个不同details的记录都会单独成行。要实现按operation_id聚合details,根据你要的两种输出形式,分别可以用以下写法:
方案1:所有details合并到单列(通用推荐)
直接使用make_list聚合函数,将同组的所有details对象存入一个动态数组列,不限制每组的记录数量:
exceptions | where timestamp > now() - 10m | summarize all_details = make_list(details) by operation_id
输出结果示例:
| operation_id | all_details |
|---|---|
| 1 | [{"cause":"sometext"},{"other_info":240},{"message":"blabal"}] |
| 2 | [{"cause":"some other text"},{"other_info":88},{"message":"blabal2"}] |
如果需要把所有details的属性合并为单个JSON对象(同名字段会被后出现的值覆盖),可以把make_list替换为make_bag:
exceptions | where timestamp > now() - 10m | summarize merged_details = make_bag(details) by operation_id
该写法的输出示例:
| operation_id | merged_details |
|---|---|
| 1 | {"cause":"sometext","other_info":240,"message":"blabal"} |
| 2 | {"cause":"some other text","other_info":88,"message":"blabal2"} |
方案2:拆分为序号独立列(匹配给出的期望输出格式)
如果需要固定生成details_1/details_2/details_3这类按序号拆分的列,可以先给组内记录打序号,再通过pivot展开列:
exceptions | where timestamp > now() - 10m // 按operation_id分组,给组内记录按指定顺序打序号,这里用timestamp排序保证顺序稳定 | partition by operation_id ( order by timestamp asc | extend rn = row_number_dense(1, 0) ) | extend col_name = strcat("details_", rn) // 按生成的列名展开 | evaluate pivot(col_name, any(details), operation_id)
输出结果和期望表完全一致:
| operation_id | details_1 | details_2 | details_3 |
|---|---|---|---|
| 1 | {"cause": "sometext"} | {"other_info": 240} | {"message": "blabal"} |
| 2 | {"cause": "some other text"} | {"other_info": 88} | {"message": "blabal2"} |
注意:该写法如果某个operation_id下的记录数超过3,会自动生成
details_4、details_5等后续列,如果每组记录数不固定,更推荐使用方案1的数组/合并对象形式。
内容的提问来源于stack exchange,提问作者Bassie
相关产品推荐
相关产品推荐

