bag_unpack处理空表后无法执行project/extend操作问题咨询
问题根因
这个问题本质是Kusto在查询编译阶段就会校验列的存在性,而bag_unpack的输出列是基于输入数据的动态属性推断的。当bag_unpack的输入是空表时,没有样本可以推断出key列的存在,编译阶段就会报错,和运行时表有没有数据无关。
可行解决方案
方案1:提前合并默认属性,保证列一定存在
最稳妥的方案,在解析JSON之后,先把你需要的所有属性的默认值合并到动态对象里,这样不管输入有没有数据、JSON里有没有对应属性,bag_unpack都能稳定输出目标列。
datatable (Date:datetime, JSON:string ) [datetime(1910-06-11), '{"key": "1"}', datetime(1930-01-01), '{"key": "2"}', datetime(1953-01-01), '{"key": "3"}', datetime(1997-06-25), '{"key": "4"}'] | where Date > datetime(2000-01-01) | project parsed = merge(dynamic({"key": ""}), parse_json(JSON)) // 合并默认属性,优先保留JSON原有值 | evaluate bag_unpack(parsed) | project-rename value = key
方案2:用column_ifexists函数兼容缺失列
如果不想修改bag_unpack的逻辑,可以在操作列之前先用column_ifexists做兼容,当列不存在时返回默认值,同时生成该列:
datatable (Date:datetime, JSON:string ) [datetime(1910-06-11), '{"key": "1"}', datetime(1930-01-01), '{"key": "2"}', datetime(1953-01-01), '{"key": "3"}', datetime(1997-06-25), '{"key": "4"}'] | where Date > datetime(2000-01-01) | project parsed = parse_json(JSON) | evaluate bag_unpack(parsed) | extend key = column_ifexists("key", "") // 列不存在时补默认空值,生成key列 | project-rename value = key
这个方法适合需要兼容的列比较少的场景,不需要提前知道动态对象的全量属性,只需要给用到的列做兼容即可。
性能说明
你目前把where过滤放在最前面的写法是完全正确的,Kusto的查询优化器会执行谓词下推,优先过滤掉不需要的行,再执行后续的JSON解析和拆解操作,不会处理全量数据,不需要把过滤条件下移,下移反而会增加不必要的计算开销。
内容的提问来源于stack exchange,提问作者Jeff McAffer
相关产品推荐
相关产品推荐

