MarkLogic 中的路径表达式 cts.search
Path expression in MarkLogic cts.search
我的印象是 MarkLogic 中的 XQuery 和服务器端 JavaScript API 在很大程度上是等效的。但是 cts:search
和 cts.search
似乎有很大的不同。在 cts:search
中,我可以指定要搜索和 return 的元素。例如,我可以从食谱书中检索所有使用肉桂作为原料的食谱:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
而 cts.search
不接受路径表达式并将 return 整个食谱书文档:
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>
这是有技术原因的。 XQuery 中的 cts:search
函数实际上不是函数,而是具有函数语法的特殊形式。这意味着第一个参数实际上并没有得到评估然后传递给函数(如果你考虑一下,那将是一种非常低效的处理方式!)。在Javascript中,cts.search
函数是一个实函数。为了避免效率低下,我们删除了第一个参数,因此您需要将您关心的部分从结果中拉出来。
如果您想将结果集限制在元素 recipe
内,请用 cts:element-query(xs:QName("recipe"), $your-query)
包裹您的查询
这会让你们更接近
https://docs.marklogic.com/cts.elementQuery
根据需要应用 cts.andQuery。
在很大程度上,JS 和 XQuery 接口在功能上是等价的,但有几个地方(这是一个)语言本身不直接支持等价。另一个是 XQuery 序列,它在 JS 中没有本机等效项——因此通过额外的 JS 类.
提供
任何 cts(复杂)查询都可以从原始 cts 查询中构造出来 objects/methods。 XQuery cts::search() 中的第一个参数是 'searchable expression' —— 它与约束范围本质上相同 —— 可以与 cts.andQuery 结合产生相同的效果(在两个 XQuery 中和JS)。根据您在 XQuery 中使用的确切表达式,您需要为 JS(或 xquery)找到等效的 cts.query。
因此 cts.elementQuery 类似于 cts::search(//element-name, ..)
考虑到 cts:search() 的 javascript 版本缺少 xquery 版本的第一个参数——我看不出它怎么能 return 除了文档节点之外的任何东西。
cts:search 和 cts.search 使用的索引优化具有 'fragments' 的粒度(通常是文档)——旨在找到潜在无限集合中的少数匹配文档。从那里您需要遍历文档的结构。 XQuery 特别擅长这一点——路径遍历是该语言的原生特性,JavaScript 没那么多。
我建议您使用 search.search 而不是 cts:search -- 它是更高级别的 API,旨在简化此类任务。
在 DALDEI 的回答的基础上,您可以使用搜索 api 到 return 只有配方元素:
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
此代码return是配方元素的节点列表。您提供的书的结果将是这个单一元素节点:
<recipe xmlns:search="http://marklogic.com/appservices/search">
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
这不是一个很好的解决方案(就快速和简单而言),但它可以作为一种解决方法。
我也尝试过使用 jsearch 函数,但没有找到传递 searchable-expression
参数的方法。我可能错过了,因为我还没有经常使用它。
进一步阅读:
我的印象是 MarkLogic 中的 XQuery 和服务器端 JavaScript API 在很大程度上是等效的。但是 cts:search
和 cts.search
似乎有很大的不同。在 cts:search
中,我可以指定要搜索和 return 的元素。例如,我可以从食谱书中检索所有使用肉桂作为原料的食谱:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
而 cts.search
不接受路径表达式并将 return 整个食谱书文档:
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>
这是有技术原因的。 XQuery 中的 cts:search
函数实际上不是函数,而是具有函数语法的特殊形式。这意味着第一个参数实际上并没有得到评估然后传递给函数(如果你考虑一下,那将是一种非常低效的处理方式!)。在Javascript中,cts.search
函数是一个实函数。为了避免效率低下,我们删除了第一个参数,因此您需要将您关心的部分从结果中拉出来。
如果您想将结果集限制在元素 recipe
内,请用 cts:element-query(xs:QName("recipe"), $your-query)
这会让你们更接近
https://docs.marklogic.com/cts.elementQuery
根据需要应用 cts.andQuery。
在很大程度上,JS 和 XQuery 接口在功能上是等价的,但有几个地方(这是一个)语言本身不直接支持等价。另一个是 XQuery 序列,它在 JS 中没有本机等效项——因此通过额外的 JS 类.
提供任何 cts(复杂)查询都可以从原始 cts 查询中构造出来 objects/methods。 XQuery cts::search() 中的第一个参数是 'searchable expression' —— 它与约束范围本质上相同 —— 可以与 cts.andQuery 结合产生相同的效果(在两个 XQuery 中和JS)。根据您在 XQuery 中使用的确切表达式,您需要为 JS(或 xquery)找到等效的 cts.query。
因此 cts.elementQuery 类似于 cts::search(//element-name, ..)
考虑到 cts:search() 的 javascript 版本缺少 xquery 版本的第一个参数——我看不出它怎么能 return 除了文档节点之外的任何东西。 cts:search 和 cts.search 使用的索引优化具有 'fragments' 的粒度(通常是文档)——旨在找到潜在无限集合中的少数匹配文档。从那里您需要遍历文档的结构。 XQuery 特别擅长这一点——路径遍历是该语言的原生特性,JavaScript 没那么多。
我建议您使用 search.search 而不是 cts:search -- 它是更高级别的 API,旨在简化此类任务。
在 DALDEI 的回答的基础上,您可以使用搜索 api 到 return 只有配方元素:
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
此代码return是配方元素的节点列表。您提供的书的结果将是这个单一元素节点:
<recipe xmlns:search="http://marklogic.com/appservices/search">
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
这不是一个很好的解决方案(就快速和简单而言),但它可以作为一种解决方法。
我也尝试过使用 jsearch 函数,但没有找到传递 searchable-expression
参数的方法。我可能错过了,因为我还没有经常使用它。
进一步阅读: