MarkLogic cts:元素查询误报?

时间:2016-05-23 18:35:48

标签: xquery marklogic false-positive

鉴于此文件: -

<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 = T1 value = V2 。 对我而言,这似乎是一种误报。

我误解了cts:element-query是如何运作的吗? (我必须说文档在这方面不是特别清楚)。

或者 MarkLogic 努力向我提供我期望的结果,并且如果我有更多或更好的索引,我就不太可能得到误报。

2 个答案:

答案 0 :(得分:5)

除了@wst的回答之外,您只需启用element value positions即可获得未经过滤的搜索的准确结果。这里有一些代码可以显示:

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'
)

如果未启用element value positions,则返回测试文档。启用位置后,查询不返回任何内容。

正如@wst所说,默认情况下cts:search()运行过滤,而cts:uris()(例如xdmp:estimate()仅运行未过滤。

HTH!

答案 1 :(得分:4)

是的,我认为这是对查询如何工作的轻微误解。在cts:search中,默认行为是启用filtered选项。在这种情况下,ML将仅使用索引来评估查询,然后一旦选择了候选文档,它就会将它们加载到内存中,检查并过滤掉误报。这更耗时,但更准确。

cts:uris是一个词典函数,因此传递给它的查询只能通过索引解析,并且没有选项可以过滤误报。

通过索引处理此查询的简单方法是更改​​架构,使文档基于<item>而不是<items>。然后每个项目都有一个单独的索引条目,结果在过滤之前不会混合。

另一种不涉及更新文档的方法是将您希望出现的查询包装在cts:near-query的同一元素中。这样可以防止一个<type>中的<item>与另一个<value>中的<item>匹配。我建议阅读文档,因为您可能需要为cts:near-query启用一个或多个基于位置的索引才能准确。