With the following query, you can check if UPDINDEX is enabled in your database:
db:info('your-db')//updindex
But it’s a fine alternative to use maps, as proposed by Graydon.
On Tue, Jul 27, 2021 at 11:16 PM Graydon graydonish@gmail.com wrote:
On Tue, Jul 27, 2021 at 04:43:16PM -0400, Matthew Dziuban scripsit:
Thanks again, Christian. Regardless of whether I have the UPDINDEX and AUTOOPTIMIZE options enabled, I'm seeing that my first set of updates runs pretty quickly (in about 90 seconds) but any subsequent set of updates hangs indefinitely -- I let it run for over 2 hours and it never completed. Do you have any idea what could be going on?
Christian may well be able to tell you specifically, but in general, it sounds like some resource is thrashing.
I think, starting from:
for $e in (db:open("source_db")/root/element) return ( if (exists(db:open("target_db")/root/element[@id = data($e/@id)])) then replace node db:open("target_db")/root/element[@id = data($e/@id)] with $e else insert node $e into db:open("target_db")/root )
I would write it as:
(: we want to open dbs once and only once because we're superstitious about that :) let $sourceDB as document-node() := db:open('source_db') let $targetDB as document-node() := db:open('target_db')
(: map id values to elements:) let $sourceElemMap as map(xs:string,element(element)) := map:merge( for $each in $sourceDB/root/element let $key as xs:string := $each/@id/string() return map:entry($key,$each) )
(: do it again; if the real data is this similar, this is a good candidate for a function :) let $targetElemMap as map(xs:string,element(element)) := map:merge( for $each in $targetDB/root/element let $key as xs:string := $each/@id/string() return map:entry($key,$each) )
(: get the ids as sequences of string values :) let $sourceIds as xs:string+ := map:keys($sourceElemMap) let $targetIds as xs:string+ := map:keys($targetElemMap)
(: do the update :) for $new in $sourceIds return if ($new = $targetIds) then replace node $targetElemMap($new) with $sourceElemMap($new) else insert node $sourceElemMap($new) into $targetDB/root
I think this does what you intend, and it might be more comprehensible to the optimizer. (I have this knack for confusing the optimizer, and it's made me cautious.)
It's not as elegant in expression and certainly not as compact. But it does somewhat separate the what-to-write and where-to-write steps, and gets the logic away from the path operator. (which, by the spec, is obliged to do a lot. If it's not needed, I find it can help to avoid it.)
-- Graydon Saunders | graydonish@gmail.com Þæs oferéode, ðisses swá mæg. -- Deor ("That passed, so may this.")