简体   繁体   中英

How to add collections in transformations when writing(creating) a Document in MarkLogic

I wrote a transformation in xquery which unquotes an XML-String and inserts a element with its content. This works fine. I need to create a collection dependant on the root element of this element as well. I can't do this on new documents as xdmp:document-add-collections() is not working. How do I add the collection to new Documents in transformations?

Here my ServerSide xQuery Code:

xquery version "1.0-ml";

module namespace transform = "http://marklogic.com/rest-api/transform/smtextdocuments";
import module namespace mem = "http://xqdev.com/in-mem-update" at '/MarkLogic/appservices/utils/in-mem-update.xqy';

declare function transform(
        $context as map:map,
        $params as map:map,
        $content as document-node()
) as document-node()
{
    let $uri := base-uri($content)
    let $doccont := $content/smtextdocuments/documentcontent
    let $newcont := xdmp:unquote($doccont)
    let $contname := node-name($newcont/*)
    let $result := if ( exists($content/smtextdocuments/content))  
    then mem:node-replace($content/smtextdocuments/content, <content>11{$newcont}</content>)
    else mem:node-insert-after($doccont, <content>{$newcont}</content>)
    let $log := xdmp:log($content)
    return (
        $result,
        xdmp:document-add-collections($uri, fn:string($contname)),
        xdmp:document-remove-collections($uri, "raw")
    )
};

The script ist running with the java api (4.0.4) create methode via parameter ServerTransform transform. As per documentation the transformation script is running before the document is stored in the Database.

Its a new document; I need to transform the content and then create the collection.

I can see the document after the create, the content is available. Just the collection is missing. I can try xdmp:document-insert method but is it correct writing the document while create is running?.

The transform mechanism of the Java API / REST API takes responsibility for the document write. At present, there's no way for the transform to supply collections to the writer. That would be a reasonable request for enhancement.

The transform shouldn't attempt to write the document, because the writer would also attempt to write the same document.

One alternative would be to transform the document in Java before writing it and specify the collection as part of the write request.

Another alternative would be to rewrite the transform as a resource service extension, implement the write within the resource service extension, and modify the Java client to send the document to the resource service extension.

Depending on the model, a final alternative might be to use a range index on an element within the document to collect documents into sets instead of using a collection on the document.

Hoping that helps,

What do you mean by "new documents"? Is the document already inserted into the MarkLogic database at the time you are adjusting the collections of it? If not, you may want to modify your return to ($result, xdmp:document-insert($uri, $result, xdmp:default-permissions(), fn:string($contname)) ) for that case.

Otherwise, can you edit your question to share the error or problem more specifically you are facing?

It is a pity that REST transforms do not allow this, like MLCP transforms do. Until changed you have the options drawn by ehennum, or you can consider delaying adding of collections to a pre- or post-commit trigger. It takes some overhead, but it sometimes makes perfect sense to do something like that in a trigger, since it makes sure it is always enforced, and a good place to do content validation, audit logging, and things like that as well.

HTH!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM