马克逻辑(MarkLogic)cts:element-query出现误报?

6

假设有以下文档:

<items>
  <item><type>T1</type><value>V1</value></item>
  <item><type>T2</type><value>V2</value></item>
</items>

不出所料,我发现这将在cts:uris()中回拉页面:

cts:and-query((
  cts:element-query(xs:QName('item'),
    cts:element-value-query(xs:QName('type'),'T1')
    ),
  cts:element-query(xs:QName('item'),
    cts:element-value-query(xs:QName('value'),'V2')
    )
  ))

但有些令人惊讶的是(至少对我来说),我也发现这个也可以:

cts:element-query(xs:QName('item'),
  cts:and-query((
    cts:element-value-query(xs:QName('type'),'T1'),
    cts:element-value-query(xs:QName('value'),'V2')
    ))
  )

这似乎不正确,因为没有单个项目具有type=T1value=V2。对我来说,这似乎是一个误报。
我是否误解了cts:element-query的工作方式? (必须说,文档在这个领域并不特别清晰。)
还是这是MarkLogic努力给我期望的结果,如果我有更多或更好的索引,就不太可能出现误报匹配。
2个回答

5
除了@wst的答案之外,您只需要启用元素值位置即可从未过滤的搜索中获得准确的结果。这里是一些代码来展示这个问题:
xdmp:document-insert("/items.xml", <items>
  <item><type>T1</type><value>V1</value></item>
  <item><type>T2</type><value>V2</value></item>
</items>);

cts:search(collection(),
  cts:element-query(xs:QName('item'),
    cts:and-query((
      cts:element-value-query(xs:QName('type'),'T1'),
      cts:element-value-query(xs:QName('value'),'V2')
    ))
  ), 'unfiltered'
)

没有启用元素值位置,这将返回测试文档。启用位置后,查询不返回任何内容。
如@wst所说,cts:search()默认情况下会运行过滤器,而cts:uris()(例如xdmp:estimate())只会运行未过滤的内容。
希望对您有帮助!

这更符合我的预期。谢谢。 - Andy Key

4
是的,我认为这是对查询方式的一种轻微误解。在cts:search中,默认情况下启用filtered选项。在这种情况下,ML将仅使用索引来评估查询,然后选择候选文档后,它将将它们加载到内存中,并检查和过滤出假阳性。这样更耗时,但更准确。 cts:uris是一个词汇表函数,因此传递给它的查询将仅通过索引解析,没有过滤假阳性的选项。
通过索引处理此查询的简单方法是更改架构,使文档基于<item>而不是<items>。然后每个项目都将有一个单独的索引条目,结果在过滤之前不会混合。
另一种不涉及更新文档的方法是将您希望发生的查询包装在同一元素中的cts:near-query中。这将防止一个<type>在一个<item>中与一个不同的<item>中的<value>匹配。我建议阅读文档,因为您可能需要启用一个或多个基于位置的索引才能使cts:near-query准确。

我理解搜索和过滤之间的区别,有时会出现误报,但这种情况非常罕见。我原本期望的是两个cts:element-value-query在同一个cts:element-query中,它们的匹配结果必须在元素(名为item)的同一实例中,而不仅仅是在任何旧的名为item的元素中。语法确实表明了我给出的两个示例意图不同。我不知道cts:near-query是否是通用情况下的答案,实际上类型和值可能相距甚远。 - Andy Key
@AndyKey 在第一种情况下,这只在筛选搜索中才是真实的。索引的分辨率仅限于文档级别。索引并不“看到”这些值位于不同的项目中,只是它们对于文档中的某些项目返回为真。通过启用位置索引并使用 cts:near-query,您可以解决这个问题。 - wst
已接受为答案。然而,似乎进行了一项检查,以确保类型和值存在于项目下方(而不仅仅是返回所有具有匹配类型和值的文档,无论它们是否在项目下方),但却没有检查匹配是否出现在同一个项目下。 - Andy Key
@AndyKey 这只是一个简化,但可以将索引原语视为键/值对,其中键是元素QName,就你的查询而言,该项与其名称没有不同的标识。标识实际上仅存在于文档/片段级别,这就是为什么它不区分相同名称的元素,即使是像这样的嵌套查询也是如此。 - wst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接