MarkLogic cts.search中的路径表达式

问题描述 投票:4回答:4

我的印象是MarkLogic中的XQuery和服务器端JavaScript API在很大程度上是等效的。但是cts:searchcts.search似乎有很大差异。在cts:search中,我能够指定要搜索和返回的元素。例如,我可以使用cinnaomon作为食谱书中的成分来检索所有食谱:

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>
marklogic
4个回答
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参数的方法。我可能错过了,因为我还没有使用过这个。

进一步阅读:

Query Options Reference search:search


5
投票

有这样的技术原因。 XQuery中的cts:search函数实际上不是函数,而是具有函数语法的特殊形式。这意味着第一个参数实际上没有被评估,然后传递给函数(如果你考虑它,这将是一个非常低效的方法继续!)。在Javascript中,cts.search函数是一个真正的函数。为了避免效率低下,我们删除了第一个参数,因此您需要从结果中拉出您关心的部分。

如果要将结果集约束到元素recipe中的结果集,请使用cts:element-query(xs:QName("recipe"), $your-query)包装查询


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
投票

鉴于cts:search()的javascript版本缺少xquery的版本'第一个参数 - 我没有看到它如何返回除文档节点之外的任何内容。 cts:search和cts.search使用的索引优化具有“片段”(通常是文档)的粒度 - 旨在查找可能无界集的少数匹配文档。从那里你需要遍历文档的结构。 XQuery在这方面特别擅长 - 路径遍历本身就是语言,而不是JavaScript。

我建议你使用search.search而不是cts:search - 它是一个更高级别的API,旨在使这样的任务更容易。

© www.soinside.com 2019 - 2024. All rights reserved.