【问题标题】:Node update in Marklogic DBMarklogic DB 中的节点更新
【发布时间】:2012-08-01 19:28:25
【问题描述】:

我有多个员工 xml 文档保存在带有文档 uri (/employee/*.xml) 的 ML DB 中,我想从唯一引用键是 roleID 的新 XML 中获取更新(在 ML XML 中它的 roleID 和新 XML它是新角色 ID)。每当找到匹配项时,它应该用新 XMl 的 newFirstName 更新 ML xml 的 firstName 值,用 newlastName 更新 lastname 值,用新 dep 更新 dep,xml 结构的其余部分应该保持不变。

Marklogic XML 结构如下:

    doc uri /employee/1.xml
    <employee>
        <firstName>Jim</firstName>
        <lastName>Day</lastName>
        <dep>IT</dep>
        <city>Boston</city>
        <roleID>1111<roleID>
        <internalID>2222</internalID>
    </employee>

    doc uri /employee/2.xml
    <employee>
        <firstName>Jan</firstName>
        <lastName>Silly</lastName>
        <dep>Finance</dep>
        <city>DC</city>
        <roleID>3333<roleID>
        <internalID>4444</internalID>
    </employee>

    doc uri /employee/3.xml
    <employee>
        <firstName>Jack</firstName>
        <lastName>John</lastName>
        <dep>HR</dep>
        <city>Virginia</city>
        <roleID>5555<roleID>
        <internalID>6666</internalID>
    </employee>

我正在尝试这个但不确定如何更新文档,而且它似乎没有优化 xquery,请帮助。

    let $newXML := <employees>
                        <newemployee>
                            <NewfirstName>New Fname1</newfirstName>
                            <newlastName>New Lname1</newlastName>
                            <newdep>New Dep1</newdep>
                            <newcity>Boston</newcity>
                            <newroleID>1111<newroleID>
                            <internalID>2222</internalID>
                        </newemployee>
                        <newemployee>
                            <newfirstName>New Fname2</newfirstName>
                            <newlastName>New Lname</newlastName>
                            <newdep>New Dep</newdep>
                            <newcity>Boston</newcity>
                            <newroleID>5555<newroleID>
                            <newinternalID>6666</newinternalID>
                        </employee>
                    </employees>
    for $oldXML in doc("/employee/*.xml")/employee
        where $newXML/newemployee/newroleID eq $oldXML/roleID
        return
          for $Matched in $oldXML
            return
            let $finalXML := 
                (: Not sure how to update some nodes in given URI, where rest of structure remain same :)

                <employee>
                    <firstName>{$newXML/newemployee/newfirstName/text()}</firstName>
                    <lastName>{$newXML/newemployee/newlastName/text()}</lastName>
                    <dep>{$newXML/newemployee/newdep/text()}</dep>              
                </employee>

【问题讨论】:

    标签: xml marklogic


    【解决方案1】:

    xdmp:node-replace

    来自文档示例:

    (: insert the doc :)
    xdmp:document-insert("/example.xml", <a><b>bbb</b></a>);
    (: replace the b node in the doc with this c node :)
    xdmp:node-replace(doc("/example.xml")/a/b, <c>ccc</c>);
    doc("/example.xml") => <a><c>ccc</c></a>
    

    【讨论】:

      【解决方案2】:

      表达式doc("/employee/*.xml") 不起作用。使用xdmp:directory 会,前提是创建目录(自动或手动)。或者,您可以使用 cts:uri-match 来查找员工的 uri,然后将其传递给 doc(),前提是 URI 词典已启用。

      但是.. 您的方法中最大的瓶颈是遍历所有文档。那是没有必要的。如果 roleID 是唯一的,则将其用于 uri,因此您无需遍历所有文档,只需立即打开正确的文档即可。或者,使用可由 XQuery 处理器优化的表达式,或仅依赖于索引。类似于以下内容:

      doc()[//roleID = $newRoleID]
      

      或者:

      cts:search(doc(), cts:element-value-query(xs:QName("roleID"), $newRoleID))
      

      对于更新本身,您可以使用xdmp:node-replace 和@sgarrett 建议的相关内容,但您也可以简单地重新创建整个 XML,并使用 xdmp:document-insert 完全替换它。无论如何,文档在幕后被完全替换,因此您几乎不会注意到与这么小的文档有任何区别。

      HTH!

      【讨论】:

      • 我认为 cts:search 比使用谓词执行 doc() 更快,但我可能错了。
      • @sgarrett 高度依赖于优化器是否认为它可以被优化。可能需要对确切的语法进行一些摆弄。像xdmp:plan 这样的函数可以帮助解决这个问题,但时间也应该足够了。如果经过优化,XPath 路由的执行速度与 cts:search 路由一样快。它们的意思完全一样。
      • xdmp:directory("/employee/", $depth) 需要创建目录,既不需要手动也不需要自动。它使用通用索引。见blakeley.com/blogofile/2012/03/19/directory-assistance
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-29
      • 2018-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多