我有一些看起来像这样的数据:
<wrapper>
<inner a="1"/>
<inner a="2" b="3"/>
</wrapper>
每个内部元素上可能存在也可能不存在属性b。我的目的是查找所有包含至少一个不带属性b。*
的内部元素的文档。This similar question提出了答案:
cts:not-query(cts:element-attribute-value-query(xs:QName('inner'), xs:QName('b'), '*', ("wildcarded"))))
但这不起作用,因为同一文档上的 some 内部元素可能具有属性b,并且非查询在整个片段上起作用,因此像上面示例中那样的混合情况将不起作用被退回。将其包装在元素查询中无济于事,并且cts:and-not-query的行为似乎相同。
我还尝试使用共现/值函数读取相关属性a的值来解决该问题,但这似乎是不可能的。除了没有元素文本之外,共现调用上的接近设置可能有可能,因此该属性使用相同的单词位置编制索引。
钝器xpath可以替代吗?
//inner[@a and not(@b)]
答案 0 :(得分:1)
如果简单性不是您的目标,则始终可以使xpath更加复杂。 这个怎么样:(它可以更准确地回答“返回包含不带@b属性的'innner'元素的所有文档”的确切问题
doc()[exists(//inner[not(@b)])]
我不知道这样做的优化程度-有些xpath表达式可以优化到等效的cts:查询,有些则没有。
还有另一个“技巧”,涉及组合以地图表示的cts表达式。进行2个搜索的结果,使用将结果作为地图返回的选项,然后您可以使用此页面https://developer.marklogic.com/blog/im-a-map上的操作来进行极其有效的设置操作(联合,交集,差等)。如果正确构建,该技术可以与“本机” cts搜索一样快--- cts搜索内部使用相同的通用技术来解析结果。
答案 1 :(得分:0)
使 XPath 成为路径范围索引。 //inner[@a and not(@b)]
,或者如果没有元素文本,//inner[@a and not(@b)]/@a
,则执行
cts:path-range-query('//inner[@a and not(@b)]/@a','>','')
这恰好也让我们能够使用 @a
有效地回答哪些 @b
值缺少 cts:values
的问题。