Problem

You want to change the URI of a document that is already in your database.

Solution

// MarkLogic 8+ for JavaScript
declareUpdate();

var oldURI = '/foo.txt'; // change to original URI
var newURI = '/bar.txt'; // change to desired URI
[oldURI, newURI].map(uri => xdmp.lockForUpdate(uri));

var propNS = fn.namespaceUriFromQName(xs.QName('prop:properties'));
var props = fn.head(xdmp.documentProperties(oldURI));

xdmp.documentInsert(
  newURI,
  fn.doc(oldURI),
  xdmp.documentGetPermissions(oldURI),
  xdmp.documentGetCollections(oldURI)
);

xdmp.documentDelete(oldURI);

if (props !== null) {
  xdmp.documentSetProperties(
    newURI,
    props.xpath('/node()/node()')
      .toArray()
      .filter(prop => fn.namespaceUri([prop]) !== propNS )
  )
}
xquery version "1.0-ml";

let $old-uri := '/uri1.xml' (: change to original URI :)
let $new-uri := '/uri2.xml' (: change to desired URI :)
let $lock := ($old-uri, $new-uri) ! xdmp:lock-for-update(.)
let $prop-ns := fn:namespace-uri-from-QName(xs:QName("prop:properties"))
let $properties :=
  xdmp:document-properties($old-uri)/node()/node()
    [ fn:namespace-uri(.) ne $prop-ns ]
return (
  xdmp:document-insert(
    $new-uri,
    fn:doc($old-uri),
    xdmp:document-get-permissions($old-uri),
    xdmp:document-get-collections($old-uri)
  ),
  xdmp:document-delete($old-uri),
  xdmp:document-set-properties($new-uri, $properties)
)

Required Privileges:

  • Update permission on the old URI
  • Privilege to insert at the new URI

Discussion

Moving a document from one URI to another is a two step process. Rather than move it, we’ll copy to the new location, then delete the original. We’ll do this in a single transaction to ensure that the process completes atomically — that is, that either both operations succeed, or neither does.

In the code above, change $old variable to the URI where the document current exists. Change the $newvariable to the URI where you want to move the document.

Notice that in the document insert function call, we retrieve the permissions and collections for the existing document. If we failed to do this, we would get the default permissions and default collections of the current user.

In addition to moving the document itself, we have to replicate the properties, if there are any. System properties can’t be written (for instance, prop:last-updated), but anything added by your application can be inserted into the properties fragment of the new document. We identify system properties by looking for the built-in properties namespace.

In MarkLogic, there are four types of permissions: read, update, insert, and execute. In order to run the code, the current user must have read and update permissions (deleting the document requires update). To create the new document, the user must have privileges to create a document at the specified URI. This can be done with either specific URI privileges, or with one of the any-uri or unprotected-uri privileges. See Creating Documents in the Security Guide for details.

Learn More

Application Developer's Guide

Read the methodologies, concepts, and use cases related to application development in MarkLogic Server, with additional resources.

MarkLogic Developer Learning Track

Want to build that awesome app? Get off the ground quickly with the developer track, with instructor-led and self-paced courses.

Getting Started Video Tutorials for Developers

This series of short videos tutorials takes developers who are new to MarkLogic from download to data hub, fast.

This website uses cookies.

By continuing to use this website you are giving consent to cookies being used in accordance with the MarkLogic Privacy Statement.