Marklogic:查找包含没有特定属性的元素的文档(每个文档可能有很多)

Marklogic: Find documents containing elements without a particular attribute (maybe many per document)

我有一些数据看起来像这样:

<wrapper>
  <inner a="1"/>
  <inner a="2" b="3"/>
</wrapper>

属性 b 可能存在也可能不存在于每个内部元素上。我的目标是找到包含至少一个没有属性 b.*

的内部元素的所有文档

提出答案:

cts:not-query(cts:element-attribute-value-query(xs:QName('inner'), xs:QName('b'), '*', ("wildcarded"))))

但这不起作用,因为同一文档中的一些内部元素可能具有属性b,并且非查询对整个片段起作用,所以混合情况如上面的例子不会被退回。将它包装在元素查询中没有帮助,cts:and-not-query 似乎表现相同。

我也尝试过使用 co-occurrence/values 函数来读取相关属性 a 的值来解决这个问题,但这似乎也是不可能的。除非没有元素文本,否则在共现调用上使用邻近设置可能是可能的,因此该属性使用相同的词位置进行索引。

是否有替代直接 xpath 的方法?

//inner[@a and not(@b)]

如果简单不是您的目标,您总是可以使 xpath 更复杂。 这个怎么样:(它更准确地回答了“return 所有包含 'innner' 没有属性 @b 的元素的文档”

的确切问题
doc()[exists(//inner[not(@b)])]

我不知道这优化得有多好 -- 一些 xpath 表达式优化到等效的 cts: query 而有些则没有。

还有另一个 'trick' 涉及组合表示为映射的 cts 表达式。取 2 次搜索的结果,使用 return 结果作为映射的选项,然后您可以使用此页面上的操作 https://developer.marklogic.com/blog/im-a-map 进行非常高效的集合操作(​​并集、交集、差异等) .如果构造得当,此技术可以与 'native' cts 搜索一样快 --- cts 搜索在内部使用相同的通用技术来解析结果。

使 XPath 成为路径范围索引。 //inner[@a and not(@b)],或者如果没有元素文本 //inner[@a and not(@b)]/@a,则执行

cts:path-range-query('//inner[@a and not(@b)]/@a','>','')

这恰好也让我们能够使用 cts:values 有效地回答 哪个 @a 值缺少 @b 的问题。