2012-08-01 2 views
0

doc URI (/employee/*.xml)를 사용하여 ML DB에 여러 개의 employee XML 문서를 저장했습니다. 고유 한 참조 키가 roleID 인 새 XML에서 업데이트를 가져 오려고합니다 (ML XML에서 roleID이고 새 XML에서는 newroleID입니다. match가 발견 될 때마다 ML xml의 firstName 값을 new XMl의 newFirstName, lastname 값을 newlastName으로, dep를 dep로 새 dep와 xml 구조체의 나머지를 동일하게 유지해야합니다. , 도와주세요Marklogic DB의 노드 업데이트

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> 

내가이 노력하고 있지만 문서를 업데이트하는 방법을 잘가, 또한 doenst XQuery를 최적화 할 것으로 보인다 다음과 같이

Marklogic의 XML 구조입니다.

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> 

답변

3

는 문서의 예에서

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> 
1

표현 doc("/employee/*.xml")이 작동하지 않습니다. xdmp:directory을 사용하면 디렉토리가 (자동 또는 수동으로) 작성됩니다. 또는 cts:uri-match을 사용하여 직원을위한 uris를 찾고 URI 어휘가 활성화 된 경우 해당 내용을 doc() 번으로 전달할 수 있습니다.

하지만 가장 큰 병목 목은 모든 문서를 걷는 것입니다. 그럴 필요는 없습니다. roleID가 고유 한 경우 URI를 사용하여 모든 문서를 걸러 낼 필요가 없으므로 올바른 문서를 바로 엽니 다. 또는 XQuery 프로세서에서 최적화 할 수있는 식을 사용하거나 단순히 인덱스를 사용하십시오. 다음과 같은 뭔가 :

doc()[//roleID = $newRoleID] 

또는 :

cts:search(doc(), cts:element-value-query(xs:QName("roleID"), $newRoleID)) 
당신이 xdmp:node-replace를 사용할 수있는 업데이트 자체에 대한

및 @sgarrett에 의해 제안,하지만 당신은 단순히 전체 XML을 재 작성하고 xdmp 사용할 수 있기 때문에 관련 : 문서를 삽입하여 완전히 대체합니다. 문서는 장면 뒤에 완전히 대체되므로 작은 문서와의 차이점을 거의 느끼지 못합니다.

HTH!

+0

나는 cts : search가 술어로'doc()'를하는 것보다 빠르다고 생각 하겠지만, 틀릴 수도있다. – sinemetu1

+1

@sgarrett는 옵티마이 저가 최적화할 수 있는지 여부에 크게 의존합니다. 정확한 구문을 사용하여 약간의 조작이 필요할 수 있습니다. 'xdmp : plan'과 같은 함수가 도움이되지만, 타이밍도 충분히 말해야합니다. 최적화 된 경우 XPath 경로는 cts : 검색 경로와 동일하게 빠르게 수행됩니다. 그들은 똑같은 것을 의미합니다. – grtjn

+0

'xdmp : directory ("/ employee /", $ depth)'는 디렉토리 생성을 필요로하지 않으며 매뉴얼도 자동도 아니다. 유니버설 인덱스를 사용합니다. http://blakeley.com/blogofile/2012/03/19/directory-assistance/ – mblakele

관련 문제