有两种方式可以说“X 中元素的所有字段都必须符合这些条件”(FOR ALL)。
TLDR:
all_have_foo_field {
# use negation and a helper rule
not any_missing_foo_field
}
any_missing_foo_field {
some i
input.array[i]
not input.array[i].foo
}
或
all_have_foo_field {
# use a comprehension
having_foo := {i | input.array[i].foo}
count(having_foo) == count(input.array)
}
方法取决于我们的情况。如果您想知道哪些元素不满足条件,则理解很好,因为您可以使用集合算术,例如,{i | input.array[i]} - {i | input.array[i].foo} 生成不具有字段“foo”的数组索引集。您可能希望将这些表达式分配给局部变量以提高可读性。有关详细信息,请参阅文档中的此部分:https://www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all。
在这种情况下(与您链接的答案相反)我们不必使用正则表达式或类似的东西,因为对缺失/未定义字段的引用导致未定义并且未定义向外传播到表达式、查询、规则等。这在Introduction中有一定程度的介绍。
那么我们所要做的就是引用相关字段。请注意,如果“foo”字段值 false 在技术上not input.array[i].foo 将为 TRUE,但在许多情况下 undefined 和 false 可以被视为可互换(它们并不完全相同——false 是一个有效的 JSON value 而 undefined 表示缺少值。)如果您只需要匹配 undefined 那么您必须将引用的结果分配给局部变量。在理解的情况下,我们可以这样写:
# the set will contain all values i where field "foo" exists regardless
{i | _ = input.array[i].foo}
在否定的情况下,我们需要一个额外的辅助规则,因为not _ = input.array[i].foo 将是“不安全的”。我们可以这样写:
exists(value, key) { value[key] = _ }`
现在not exists(input[i], "foo") 仅在字段“foo”缺失时为 TRUE。
注意,区分 undefined 和 false 通常不值得——我建议仅在必要时这样做。