Rashmita Purkayastha
Rashmita Purkayastha

Reputation: 449

How can we delete the source contents from source database after copying them to another database in MarkLogic

I am using below xquery to copy documents from one database to another in MarkLogic. Along with copying my requirement is to remove those documents which are successfully copied. I cannot remove the collection fully as some of the documents may not get copied as they fails to get copied due to template document errors which are present in the target database.

Is there a way to get the list of the documents which are not copied and got failed due to template errors and retain them in the source database and delete the rest of them.

Here is my xquery to copy the documents -

xquery version "1.0-ml";
for $doc in cts:search(doc(), cts:collection-query('Collection1'))
let $docuri := $doc/base-uri()
let $collections := xdmp:document-get-collections($docuri)
let $permissions := xdmp:document-get-permissions($docuri)
let $document-insert-options := 
  <options xmlns="xdmp:document-insert">  
    <permissions>{$permissions}</permissions>
    <collections>{
        <collection>{$collections}</collection>
        }
        </collections> 
  </options>
let $db-name := "STAGING"  
let $invoke-function-options := 
  <options xmlns="xdmp:eval">
    <database>{ xdmp:database($db-name) }</database>
    <commit>auto</commit>
  </options>
return
 xdmp:invoke-function(
   function(){ xdmp:document-insert($docuri, $doc, $document-insert-options)},
   $invoke-function-options
 ); 
 

Upvotes: 1

Views: 35

Answers (1)

Rob S.
Rob S.

Reputation: 3609

You need to catch any error that occurs and handle it or if no error occurs then proceed with deleting the original document.

The KnowledgeBase suggests:

...execute the updates in an xdmp:eval() or an xdmp-invoke()with different-transaction isolation, and wrap the eval or invoke inside a try/catch block. In this way, The commit time errors can be caught.

To implement this change your return to:

return
 try {
  let $_ := xdmp:invoke-function(
   function(){ xdmp:document-insert($docuri, $doc, $document-insert-options)},
     $invoke-function-options
   )
  return xdmp:document-delete($docuri)
 }
 catch($exception)
 {
  (: Handle the error :)
  xdmp:rethrow() (: To stop processing and stop the application at this point if desired :) 
 }

In this code the document-delete won't run if an exception is thrown from invoke-function. Instead, execution will jump into the catch block.

An alternative approach is to do the deletes in a separate operation. You could get a list of URIs from Database 2 and then delete anything in that list that exists in Database 1.

A second alternative approach is to copy the data over using database replication and then deleting the original database once fully replicated.

A third alternative approach is to copy the data over using a backup and then deleting the original database.

Upvotes: 2

Related Questions