I am having several documents in STAGING DB.
Based on a condition i need to check if the document with same ID exist in FINAL.
If it does then i need to replace the multiple nodes of document from STAGING to FINAL and then insert it.
DOC from STAGING-
<root>
<ID>1</ID>
<value1>India</value1>
<value2>USA</value2>
<value3>Russia</value3>
<value4>Srilanka</value4>
<value5>Europe</value5>
<value6>Antartica</value6>
<value7>Spain</value7>
</root>
DOC from FINAL-
<root>
<ID>1</ID>
<value1></value1>
<value2></value2>
<value3></value3>
<value4></value4>
<value5>Europe</value5>
<value6>Antartica</value6>
</root>
OUTPUT i am expecting in FINAL-
<root>
<ID>1</ID>
<value1>India</value1>
<value2>USA</value2>
<value3>Russia</value3>
<value4>Srilanka</value4>
<value5>Europe</value5>
<value6>Antartica</value6>
<value7>Spain</value7>
</root>
From the STAGING i just need to focus on (value1,value2,value,value4,value7) and replace it. For other values i am having some different conditions so i have to ignore them.
Logic i have written in WRITER.xqy-
let $boolean := fn:false()
let $var := if((......)
then
(
let $docs :=
cts:search(doc(),cts:and-query((
cts:element-value-query(xs:QName("ID"),$id),
cts:collection-query(("MyCollection"))
)))
let $temp :=
if((fn:exists($result) eq fn:true())) then xdmp:set($boolean,fn:true()) else ()
return $docs
)
else ()
let $envelope := if($boolean)
then
(
let $nodes := ("value1,value2,value,value4,value7")
let $tokenize := fn:tokenize($nodes,",")
let $values := for $i in $tokenize
let $final := xdmp:value(fn:concat("$var//*:root/*:",$i))
let $staging := xdmp:value(fn:concat("<",$i,">","{$envelope//*:root/*:",$i,"/text()}","</",$i,">"))
let $envelope := mem:node-replace($final,$staging)
return $envelope
return $values
)
else $envelope
return
xdmp:document-insert($id,$envelope, xdmp:default-permissions(), map:get($options, "entity"))
This gives me
ERROR- ARG2 for xdmp:document-insert is NOT a NODE.
I do understand it as my $envelope
is iterating for all the NODES and returning multiple envelopes.
Any Suggestions to resolve this ?
When you use the in-mem-update function, it returns the result of the modification.
If you are going to be making a sequence of changes to the document, you need to use the product of the previous mem:* method calls as the input for the next. You can achieve that with a recursive function that either calls itself with one less element name, or returns the final result when there are no more names.
Below is an example of how it could be done. I also simplified some of the logic to use XPath to select the desired elements with a predicate filter on the
local-name()
, instead of generating strings and evaluating withxdmp:value()
. I think that it's more straightforward and easier to read.