Return 只有来自 cts:reverse 查询的 URI

Return only URIs from cts:reverse-query

更新: 见结尾 - 一个例子表明 cts:uris 不是有效的方法,因为它 return 在所有情况下都没有正确的结果。

我有一个 use-case,在 MarkLogic 中,我有时会在包含 cts:reverse 查询的搜索结果中找到数十万个匹配项。有了这个,我想要 return 的是与结果匹配的文档的 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)

还有这个 returns:

/test/reverse-baz.xml

这是预期的。

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

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

一起使用

是的,我知道 reverse-query 不一定需要作为文档存在于数据库中才能使用它(cts:contains 示例),因此在某些 use-case 中,URI 不需要;甚至不存在。但对我来说,他们这样做。

此外,我很确定我可以使用 xdmp:plan() 生成 cts:uris()[= 所需的查询63=] 通过拉出 final-plan 和 re-writing 命名空间到 cts,但我不确定这是否更快。

结合以上,(2)题如下:

  1. 对于了解 MarkLogic 内部结构的人,您是否认为 cts-search->for loop ->sdmo:node-uri() 是有效的并且影响很小(换句话说,我认为在不将文档扩展到扩展树缓存中的情况下完成此操作?)
  2. 如果没有,你能想出一种更有效的方法来模仿 cts:uris 比我上面做的更快吗?

为什么不 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/>))
  )))

Returns:
/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 只给了我全部 collection,而它本不应该给我任何东西,cts:search 给出了正确的回应。

为什么不能将 cts:reverse-query() 与 cts:uris() 一起使用?

试试这个:

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

啊 - 现在我们开始了。如所述,我得到了错误的匹配。但是,在我手动合并之后,我得到了正确的回应。因此,仔细研究预合并和 post-合并结果,看看我是否能找出原因...

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