MarkLogic cts:元素查询误报?
Posted
技术标签:
【中文标题】MarkLogic cts:元素查询误报?【英文标题】:MarkLogic cts:element-query false positives? 【发布时间】: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=T1 和 value=V2。 对我来说,这似乎是一个误报。
我是否误解了cts:element-query
的工作原理?
(不得不说,这方面的文档不是特别清楚)。
或者这是 MarkLogic 努力为我提供预期结果的地方,如果我有更多或更好的索引,我得到误报匹配的可能性就会降低。
【问题讨论】:
【参考方案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
是一个词典函数,因此传递给它的查询只能通过索引解析,并且没有过滤误报的选项。
通过索引处理此查询的简单方法是更改架构,使文档基于<item>
而不是<items>
。然后每个项目将有一个单独的索引条目,并且在过滤之前不会混合结果。
另一种不涉及更新文档的方法是将您希望在cts:near-query
中的同一元素中出现的查询包装起来。这将阻止一个<item>
中的<type>
与另一个<item>
中的<value>
匹配。我建议阅读文档,因为您可能需要为 cts:near-query
启用一个或多个基于位置的索引才能准确。
【讨论】:
我了解搜索和过滤器之间的区别,并且我确实有时会预料到误报,只是它们很少见。我所期望的是,两个 cts:element-value-query 在同一个 cts:element-query 中的事实意味着它们的匹配项必须在元素的同一个实例(命名项目)内,而不仅仅是在任何名为 item 的旧元素。语法确实表明我给出的两个示例意图不同。我不知道 cts:near-query 是否是一般情况下的答案,实际上事实类型和值可能相距甚远。 @AndyKey 在第一种情况下,这只会在过滤搜索中成立。索引的分辨率仅在文档级别。索引不会“看到”这些值在不同的项目中,只是它们对文档中的某些项目返回 true。通过启用位置索引并使用cts:near-query
,您可以解决这个问题。
接受为答案。但是,检查类型和值是否存在于项目之下似乎很奇怪(而不是仅仅返回所有类型和值匹配的文档,而不管它们是否在项目之下),但没有检查匹配发生在 same 项下方。
@AndyKey 这是一种简化,但考虑索引原语的一种方法是作为键/值对,其中键是元素 QName,并且只要它与您的查询相关,则该项目不具有与其名称不同的身份。身份实际上只存在于文档/片段级别,这就是为什么它不区分同名元素的原因,即使对于像这样的嵌套查询也是如此。以上是关于MarkLogic cts:元素查询误报?的主要内容,如果未能解决你的问题,请参考以下文章