考虑这个查询:
let set1=dynamic(["6ab1c993-c138-92ab-abac-49c4d4680812"]);
let set2=dynamic(["6ab1c993c13892ababac49c4d4680812@email.com"]);
let set3=dynamic(["6ab1c993-c138-92ab-abac"]);
let dummyData=datatable(Timestamp:datetime, DynamicData:dynamic) [
datetime(2019-12-30 01:00:00), dynamic({"Id": "6ab1c993-c138-92ab-abac-49c4d4680812", "Email": "6ab1c993c13892ababac49c4d4680812@email.com"})
];
// query1: fails: Relop semantic error: 'has_any' has the following semantic error: SEM0024: The source expression is of type 'dynamic' and cannot be compared with numeric arguments.
dummyData | where DynamicData has_any (toscalar(set1));
//
// query2: succeeds
dummyData | where DynamicData has_any (toscalar(set2));
//
// query3: succeeds
dummyData | where DynamicData has_any (toscalar(set3));
// query4: fails
dummyData | where DynamicData.Id in (toscalar(set1));
第一个查询失败,因为它认为 RHS 是数字。第二个和第三个查询成功。如果这些值来自数据,那么今天成功的查询可能会在以后出现编译错误时失败。
请注意,在这种情况下,in() 或 set_intersect() 不是选项,因为 DynamicData 是一个复杂的属性包。即使这适用于 in(),“DynamicData has_any ()”也比“DynamicData.child1.child2 in ()”快得多。
Edit1:这在 in() 上也失败了,并且似乎只要列表中的值可能映射到 GUID 就会发生。
更新了标题并添加了另一个示例。
Edit2:找到了一种不会降低性能的解决方法:将 LHS 包装在一个 tostring 中,例如 'dummyData | 其中 tostring(DynamicData) has_any (toscalar(set1));'