使用内置的 MarkLogic cts 函数,我希望能够编写一个查询,该查询可以找到如下所示的文档 -- 其中至少存在 1 个不包含
<child1>
元素的元素 (parents/parent[2]
)。但我不想从搜索结果中排除具有 <child1>
元素(parents/parent[1]
或 parents/parent[3]
)的文档。
<doc>
<root>
<parents>
<parent>
<child1>someValue</child1>
<child2>someValue</child2>
</parent>
<parent>
<child2>someValue</child2>
</parent>
<parent>
<child1>someValue</child1>
<child2>someValue</child2>
</parent>
</parents>
</root>
</doc>
我的思考过程是,简单地否定以下内容就会返回我正在寻找的内容:
正 xQuery:
let $query :=
cts:element-query(
xs:QName('parent')
,cts:element-query(
xs:QName('child1')
,cts:true-query()
)
)
return cts:search(fn:doc(),$query)
或使用搜索模块:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<extract-document-data selected="include">
<extract-path xmlns:es="http://marklogic.com/entity-services">//root</extract-path>
</extract-document-data>
<additional-query>
<cts:element-query>
<cts:element>parent</cts:element>
<cts:element-query>
<cts:element>child1</cts:element>
<cts:true-query>
</cts:true-query>
</cts:element-query>
</cts:element-query>
</additional-query>
</options>
return search:search("",$options)
导致我尝试查询:
否定 xQuery:
let $query :=
cts:not-query(
cts:element-query(
XS:QName('parent')
,cts:element-query(
XS:QName('child1')
,cts:true-query()
)
)
)
return cts:search(fn:doc(),$query)
经过进一步评估,很明显为什么“否定”查询没有按照我的预期进行评估...肯定查询返回路径
//parent/child1
存在的文档...与此相反的是“返回其中 的文档” //parent/child1
不存在”...
尽管如此,我很困惑如何利用 MarkLogic 的 cts 函数有效地做到这一点。该数据库收集了数十亿个文档,普通的 xquery/xpath 将非常耗时。我真的希望使用搜索模块/api 来实现这一目标 - 请记住(尽管上面有我的搜索模块示例),要运行此查询,我希望通过对搜索 REST 端点的 api 调用来实现,所以我将无法使用 xQuery 增强服务器端搜索。虽然如果它只能使用纯 xQuery 来实现,但它就是这样,我可以只使用 eval REST 端点。
在寻找信息时,我确实看到了 6 年前类似的帖子: 在 marklogic 中搜索 xml 中没有特定元素
但是自从提出这个问题以来已经有相当长的时间了,它被标记为 marklogic-8,而且我的问题在很大程度上有所不同,因为我希望通过开箱即用的搜索模块/api 来实现这一目标。
我对 Marklogic 中的
cts
函数一无所知,但以下 XQuery 条件测试文档是否满足您的条件
where some $p in $doc//parent satisfies empty($p/child1)
或更简洁地
where $doc//parent[not(child1)]