【问题标题】:MarkLogic cts:element-query false positives?MarkLogic cts:元素查询误报?
【发布时间】:2016-09-20 18:09:33
【问题描述】:

鉴于这份文件:-

<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 努力为我提供预期结果的地方,如果我有更多或更好的索引,我得到误报匹配的可能性就会降低。

【问题讨论】:

    标签: xquery marklogic false-positive


    【解决方案1】:

    除了@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!

    【讨论】:

    • 这更符合我的预期。谢谢。
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 我了解搜索和过滤器之间的区别,并且我确实有时会预料到误报,只是它们很少见。我所期望的是,两个 cts:element-value-query 在同一个 cts:element-query 中的事实意味着它们的匹配项必须在元素的同一个实例(命名项目)内,而不仅仅是在任何名为 item 的旧元素。语法确实表明我给出的两个示例意图不同。我不知道 cts:near-query 是否是一般情况下的答案,实际上事实类型和值可能相距甚远。
    • @AndyKey 在第一种情况下,这只会在过滤搜索中成立。索引的分辨率仅在文档级别。索引不会“看到”这些值在不同的项目中,只是它们对文档中的某些项目返回 true。通过启用位置索引并使用cts:near-query,您可以解决这个问题。
    • 接受为答案。但是,检查类型和值是否存在于项目之下似乎很奇怪(而不是仅仅返回所有类型和值匹配的文档,而不管它们是否在项目之下),但没有检查匹配发生在 same 项下方。
    • @AndyKey 这是一种简化,但考虑索引原语的一种方法是作为键/值对,其中键是元素 QName,并且只要它与您的查询相关,则该项目不具有与其名称不同的身份。身份实际上只存在于文档/片段级别,这就是为什么它不区分同名元素的原因,即使对于像这样的嵌套查询也是如此。
    猜你喜欢
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多