我的印象是MarkQuery中的XQuery和服务器端JavaScript API在很大程度上是等效的。但是cts:search
与cts.search
似乎有很大的不同。在cts:search
中,我可以指定要搜索和返回的元素。例如,我可以从食谱书中检索使用肉桂粉作为成分的所有食谱:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
cts.search
不接受路径表达式,而是返回整个食谱书文档:
cts.search(cts.elementWordQuery(xs.QName('ingredients'), 'cinnamon'))
在MarkLogic邮件列表中曾问过同样的问题,但我在那儿看不到答案:https://developer.marklogic.com/pipermail/general/2015-March/016508.html
下面是一个最小的示例:
<book>
<recipe>
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
<recipe>
<ingredients>sugar, peppermint</ingredients>
<instruction/>
</recipe>
<recipe>
<ingredients>coconut oil</ingredients>
<instruction/>
</recipe>
</book>
xquery将是:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
和响应:
<recipe>
<ingredients>cinnamon, peppermint</ingredients>
<instruction></instruction>
</recipe>
答案 0 :(得分:5)
这样做有技术原因。 XQuery中的cts:search
函数实际上不是函数,而是具有函数语法的特殊形式。这意味着第一个参数实际上没有得到评估,然后传递给函数(如果您考虑一下,那将是一种非常低效的处理方式!)。在Javascript中,cts.search
函数是一个实函数。为了避免效率低下,我们删除了第一个参数,因此您需要从结果中拉出您所关心的部分。
如果要将结果集限制为元素recipe
中的结果,请用cts:element-query(xs:QName("recipe"), $your-query)
包裹查询
答案 1 :(得分:3)
这应该使您更近
https://docs.marklogic.com/cts.elementQuery
根据需要应用cts.andQuery。
在很大程度上,JS和XQuery接口在功能上是等效的,但是在某些地方(这是其中之一),语言本身并不直接支持等效。另一个是XQuery序列,该序列在JS中没有本地等效项-因此是通过额外的JS类提供的。
可以从原始cts查询对象/方法中构造出任何cts(复杂)查询。 XQuery cts :: search()中的第一个参数是“可搜索表达式”(本质上与约束范围相同),可以与cts.andQuery结合使用以产生相同的效果(在XQuery和JS中)。根据在XQuery中使用的确切表达式,您需要为其找到与JS(或xquery)等效的cts.query。
因此cts.elementQuery类似于cts :: search(// element-name,..)
答案 2 :(得分:2)
鉴于cts:search()的javascript版本缺少xquery版本的第一个参数-我看不到它如何能返回文档节点以外的任何内容。 cts:search和cts.search使用的索引优化具有“片段”(通常是文档)的粒度-旨在查找可能无界集合中的少数匹配文档。从那里您需要遍历文档的结构。 XQuery尤其擅长于此-路径遍历是语言的本机,JavaScript并不是很多。
我建议您使用search.search而不是cts:search-它是一个高级API,旨在使此类任务更加轻松。
答案 3 :(得分:1)
基于DALDEI的答案,您可以使用搜索API仅返回配方元素:
const search = require('/MarkLogic/appservices/search/search');
let options = fn.head(xdmp.unquote(`
<options xmlns="http://marklogic.com/appservices/search">
<return-results>true</return-results>
<searchable-expression>//recipe</searchable-expression>
<extract-document-data>all</extract-document-data>
<additional-query>
<cts:element-word-query xmlns:cts="http://marklogic.com/cts">
<cts:element>ingredients</cts:element>
<cts:text xml:lang="en">cinnamon</cts:text>
</cts:element-word-query>
</additional-query>
</options>`)).root;
search.search("", options) // returns a Sequence of search:response
.toArray()[0] // get the first result
.getElementsByTagName("recipe") // find all recipe elements
此代码返回配方元素的NodeList。您提供的书的结果将是以下单个元素节点:
<recipe xmlns:search="http://marklogic.com/appservices/search">
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
这不是一个很好的解决方案(快速简便),但它可能是一种解决方法。
我也尝试使用jsearch函数,但是没有找到传递searchable-expression
参数的方法。我可能已经错过了,因为我还没有使用过。
更多读数: