如何更新不同数据库中的节点或如何更新外部节点?- XDMP-UPEXTNODES

Sha*_*ini 1 xquery marklogic

我正在尝试更新与当前数据库不同的数据库中的文档。但它给了我以下错误-

XDMP-UPEXTNODES: xdmp:node-replace(fn:doc("/C:/Users/Downloads/abc.csv-0-2")/*:envelope/*:root/*:Status, <Status>1000</Status>) -- Cannot update external nodes
Run Code Online (Sandbox Code Playgroud)

我正在使用下面的代码-

let $temp := 
  for $i in $result
  let $error := $i/*:envelope/*:ErrorMessage
  let $status := $i/*:envelope/*:Status
  return 
    if(fn:exists($i) eq fn:true()) then (
      xdmp:invoke-function(
        function() { 
          xdmp:node-replace($status,<Status>1000</Status>),
          xdmp:node-replace($error,<ErrorMessage>Change Error in other Database-2</ErrorMessage>)  
        },
        <options xmlns="xdmp:eval">
          <database>{xdmp:database("DATABASE-2")}</database>
        </options>))
    else ()
Run Code Online (Sandbox Code Playgroud)

我想更新Database-2的错误和状态节点。

$result 是我从Database-2获取的文档。

我从Database-1运行此代码

有什么建议 ?

grt*_*tjn 5

您不能将数据库节点作为变量传递以用于更新目的。相反,您应该传递数据库 uri,并获取要在调用的函数内更新的元素的新副本。也许您可以在调用的函数中添加更多逻辑,以使其更容易。就像是:

for $i in $result
let $uri := xdmp:node-uri($i)
return xdmp:invoke-function(function() {
  let $doc := fn:doc($uri)
  let $error := $doc/*:envelope/*:ErrorMessage
  let $status := $doc/*:envelope/*:Status
  return if(fn:exists($doc) eq fn:true()) then (
    xdmp:node-replace($status, <Status>1000</Status>),
    xdmp:node-replace($error, <ErrorMessage>Change Error in other Database-2</ErrorMessage>)
  ) else ()
}, map:entry("database", xdmp:database("DATABASE-2")))
Run Code Online (Sandbox Code Playgroud)

不过要小心。听起来 $i 也指向 Database-2 中的实际文档,这很容易导致死锁;调用查询可能会在 $i 上放置读锁,导致调用的函数无法更新它。

哈!