To clarify the other Reponses, there are several distinct issues to consider.
1) appending documents - in-memory vs DB. There is no Database level document append, every change you make to a document requires reading/modify/write and creates a new document. In a case as you describe, that is not a good approach for many reasons, performance , IO , possible locking issues etc instead you should create the final document image in memory. 2) transaction locking. Very important to not mix a large search in the same transaction as an update, however you can fairly easily do the update in the same 'code' but as a separate transaction by making use of xdmp:invoke() or xdmp:invoke-function() I like invoke-function because you don't need a separate XQuery file See: https://docs.marklogic.com/xdmp:invoke-function Use the <isolation>different-transaction</isolation> option as discussed here; https://docs.marklogic.com/xdmp:eval 3) How to create a document iterative in memory. The suggestions given are excellent. An alternative is to directly use the 'functional programming' paradigm that XQuery is based on - this is fundamentally different the 'procedural programming' and can take a while to 'sink in' when one is used to procedural languages. The core idea is that in functional programming languages there really is not 'iteration' in the same sense. You cannot actually update a variable (a few exceptions with some special internal functions). Instead you create the final result 'bottom up' as a single expression. This usually involves recursion instead of iteration. E.g. Where you might naturally think like this: let $doc := <doc/> return for $row in cts:search() ... add-result( $doc, $row ) return $doc That doesn't actually work. You use some techniques to get close but they tend to be inefficient and clumsy in loops, for example 'add-result' can return a new copy of $doc every time its called like $doc := add-result( $doc , $row ) This is what the various in-memory functions do. But then it is still a bit tricky to find the 'last' $doc returned, because you are not actually modifying the same $doc variable as in 'let $doc ...' instead a new variable named '$doc' is created each time (and then abandoned) so you're not actually passing the new '$doc' variable into the loop nor getting it at the end. 'Mapping' iterative procedural style to functional programming can be frustrating until you realize you need to think of the problem differently. Recursion is generally the 'natural' solution. And since almost every operation on sequences uses 'lazy evaluation' it can be much more efficient than you think - quite the opposite. In ML XQuery, passing references to sequences of arbitrary length is very efficient - it is only passing a single reference not a copy, whereas incrementally creating documents by inserting one element at a time is very inefficient - because it has to recreate the entire document for each insertion. So with Recursion you solve both problems - E.g. For simple cases this is how one can efficiently make a document out of a sequence of data. Note that this never has to update data in place let $doc := <doc>{ for $r in := cts:search( ... ) return create-element-from-one-row( $r ) }</doc> For more complex needs a recursive function like this can be used, Note that by producing not the full document each call its much faster and easier to write. declare function local:addRow( $data as element(old) * , $new as element(new)* ) as element(new) * { if( empty( $data ) ) then $new (: done ! :) else (: some more complex logic here if you want to reorder the results or look at previous values first :) local:addRow( $data[position() gt 1] , <row>{ create-row-from-data( $data[1] ) }</row> ) }; (: creates full document in one expression :) let $doc := <doc>{ local:addRow( cts:search(...) , () ) } </doc> ----------------------------------------------------------------------------- David Lee Lead Engineer MarkLogic Corporation d...@marklogic.com Phone: +1 812-482-5224 Cell: +1 812-630-7622 www.marklogic.com -----Original Message----- From: general-boun...@developer.marklogic.com [mailto:general-boun...@developer.marklogic.com] On Behalf Of Christopher Hamlin Sent: Thursday, June 18, 2015 8:42 PM To: MarkLogic Developer Discussion Subject: Re: [MarkLogic Dev General] Generating Reports in ML On Thu, Jun 18, 2015 at 4:55 PM, Kari Cowan <kco...@alm.com> wrote: > To be clear, I can take a single result and return it into a > xdmp:document-insert statement – is there a method available to > iteratively append to that document? > You can use the node insert calls as Danny suggested. But if you do, beware of multiple changes to the same document giving you conflicting-updates errors, if you mean to make >1 change to the same document in the same transaction. In that case you can just create a new document in memory with all the changes and reinsert it. There's also a library that lets you make changes to in-memory documents. /ch _______________________________________________ General mailing list General@developer.marklogic.com Manage your subscription at: http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list General@developer.marklogic.com Manage your subscription at: http://developer.marklogic.com/mailman/listinfo/general