仅返回来自cts的URI:reverse-query

时间:2016-06-06 11:58:32

标签: marklogic marklogic-8

更新:请参阅结束 - 显示cts:uris不是有效方法的检查,因为它并未在所有情况下都返回正确的结果。

我有一个用例,在MarkLogic中,我有时会在包含cts:reverse-query的搜索结果中包含数十万个匹配项。有了这个,我想要返回的是与结果匹配的文档的URI,以便我可以缓存它们并稍后通过Corb2处理它们。

示例代码:

xquery version "1.0-ml";


let $_ := xdmp:invoke-function(function(){
  for $val in ("foo", "bar", "baz")
    let $query := <query>{cts:element-word-query(xs:QName("what"), ($val))}</query>
    return (
              xdmp:document-insert("/test/reverse-" || $val ||".xml", $query, (), ("test-reverse")),
              xdmp:commit()
           )

},<options xmlns="xdmp:eval">
        <transaction-mode>update</transaction-mode>
      </options>
)


return for $result in cts:search(collection("test-reverse"), cts:reverse-query(<what>baz</what>))
  return xdmp:node-uri($result)

然后返回:

/test/reverse-baz.xml

预期。

然而,我感觉就像我在这里做了太多的处理,因为我已经有了来自cts:search()的文档。但话说回来,因为ML是懒惰的,甚至现在,我真的只有一个参考,因为我没有访问文档中的任何内容..?

我想要的是使用cts:uris()来获得与上面相同的结果。但是,你不能使用cts:reverse-query with cts:uris()

是的,我理解反向查询永远不一定需要在数据库中作为使用它的文档(cts:contains example),因此在某些用例中,URI甚至不存在。但对我来说他们确实如此。

另外,我很确定我可以使用 xdmp:plan()来拉出来生成 cts:uris()所需的查询最终计划并将命名空间重写为cts,但我不确定这是否更快。

通过以上,(2)以下问题:

  1. 对于了解MarkLogic内部的人,您会考虑使用cts-search-&gt; for loop - &gt; sdmo:node-uri()来提高效率并且影响不大(换句话说,我是在不扩展的情况下实现这一点的吗?将文档放入扩展树缓存中?)
  2. 如果没有,你能想到一个更有效的模仿cts的方法:uris以比我上面更快的方式吗?
  3. 为什么不用cts:uris() - 因为我发现没有比赛,我找回了所有内容:

    xquery version "1.0-ml";
    
    
    let $_ := xdmp:invoke-function(function(){
      for $val in ("foo", "bar", "baz")
        let $query := <query>{cts:element-word-query(xs:QName("what"), ($val))}</query>
        return (
                  xdmp:document-insert("/test/reverse-" || $val ||".xml", $query, (), ("test-reverse")),
                  xdmp:commit()
               )
    
    },<options xmlns="xdmp:eval">
            <transaction-mode>update</transaction-mode>
          </options>
    )
    
    
    return cts:uris((),(),
      cts:and-query((
        cts:collection-query("test-reverse"),
        cts:reverse-query((<foo/>))
      )))
    

    返回:
    /test/reverse-bar.xml
    /test/reverse-baz.xml
    /test/reverse-foo.xml

    最终样本显示结果的差异(验证cts:uris不起作用):

    xquery version "1.0-ml";
    
    
    let $_ := xdmp:invoke-function(function(){
      for $val in ("foo", "bar", "baz")
        let $query := <query>{cts:element-word-query(xs:QName("what"), ($val))}</query>
        return (
                  xdmp:document-insert("/test/reverse-" || $val ||".xml", $query, (), ("test-reverse")),
                  xdmp:commit()
               )
    
    },<options xmlns="xdmp:eval">
            <transaction-mode>update</transaction-mode>
          </options>
    )
    
    let $uris-from-cts-uris := cts:uris((),(),
      cts:and-query((
        cts:collection-query("test-reverse"),
        cts:reverse-query(<foo/>)
      )))
    
    let $uris-from-search := for $result in cts:search(collection("test-reverse"), cts:reverse-query(<foo/>))
      return xdmp:node-uri($result)
    
    return 
    (
      $uris-from-cts-uris,
      "xxxxxxxxxxxxxxxxx",
      $uris-from-search
    
    ) 
    

    结果如下:

    /test/reverse-bar.xml
    /test/reverse-baz.xml
    /test/reverse-foo.xml
    xxxxxxxxxxxxxxxxx

    这里写着:cts:uris刚给了我整个系列,它应该什么都不给我和cts:搜索给出了正确的答案。

2 个答案:

答案 0 :(得分:4)

为什么你不能使用cts:reverse-query()和cts:uris()?

试试这个:

cts:uris((),(),
  cts:and-query((
    cts:collection-query("test-reverse"),
    cts:reverse-query(<what>baz</what>)
  )))

答案 1 :(得分:0)

是啊 - 现在我们正在做些什么。我按照描述获得了错误的比赛。但是,在我手动合并后,我得到了正确的答案。因此,挖掘合并前和合并后的结果,看看我能否发现原因......

所以,cts:uris是有效的,但并不总是显然与合并相关......?