1

此问题与数据中心框架有关-

我有 3-4 个条件,其中我正在执行操作xdmp:node-replacexdmp:document-delete并且在所有条件之后我试图使用xdmp:document-insert.

当我通过评论其他条件独立运行条件时,它工作正常,但如果我试图一起运行 2 个或更多条件 - 我得到XDMP-CONFLICTINGUPDATES

$envelope is coming from STAGING Database which i am using in writer.xqy

代码示例如下 -

let $con1 := if($envelope/*:test/text() eq "abc")
                 then xdmp:node-replace(....) else ()
let $con2 := if($envelope/*:test/text() eq "123")
                 then xdmp:node-replace(....) else ()
let $con1 := if($envelope/*:test/text() eq "cde")
                 then xdmp:document-delete(....) else ()
return if($envelope//*FLAG/text() eq "1")
    then
   xdmp:document-insert($id, $envelope, xdmp:default-permissions(), map:get($options, "entity"))

有什么建议么 ?

4

4 回答 4

4

XDMP-ConflictingUpdates意味着您尝试在单个事务中多次更新同一个节点。解决这些类型的错误可能非常棘手,并且是每个 MarkLogician 的通行仪式。

在您的情况下,这是由使用 更新节点xdmp:node-replace然后使用 更新作为该节点的父节点的文档节点引起的xdmp:document-insert。因此,因为您正在更新节点及其父节点,所以实际上是两次更新该节点导致错误。或者,这也可能发生在尝试在同一事务中的同一 URI 处删除和插入文档时。

这是一个简单的查询,您可以在 QConsole 中运行以重现此行为:

xquery version "1.0-ml";

xdmp:document-insert("/test.xml", <test><value></value></test>);

xquery version "1.0-ml";

let $d := fn:doc("/test.xml")

let $_ := xdmp:node-replace($d//value, <value>test</value>)

return
  xdmp:document-insert("/test.xml", $d)

在此演示的情况下,以及您的代码中,xdmp:document-insert是多余的,可以简单地删除。

于 2018-07-20T13:57:54.930 回答
4

很可能上面的 XQuery 语句在同一个单语句事务中尝试对同一个节点进行多次更新。这些xdmp:node-replace调用在对同一节点的每个操作中执行更新。有关更多详细信息,请参阅文档

这里有两个可能对你有用的解决方案

  1. 使用条件语句来决定需要对节点进行什么样的更新,例如,是否需要删除节点,是否需要更新节点以及如何更新。在脚本结束时,您可以将更新行为应用于节点。
  2. 对节点执行内存更新,然后在事务结束时将节点提交到数据库。这是您可以使用的一个库https://github.com/ryanjdew/XQuery-XML-Memory-Operations
于 2018-07-20T14:00:56.387 回答
1

复杂更新的一种一般可能性:使用 XSLT。

于 2018-07-20T16:40:19.443 回答
0

这是多事务语句。在您的场景中有多种方法可以处理它:

  1. 使用 xdmp:eval
  2. 使用 MarkLogic 的 mem 库来替换你的节点
  3. 重写您的查询以避免事务冲突
于 2018-07-21T15:23:35.887 回答