MarkLogic Server 10.0-7 Streaming for XQuery FLWOR expressions
17 May 2022 07:11 PM


Starting in MarkLogic Server version 10.0-7, XQuery FLWOR expressions that only use "let" will now stream results. Prior to 10.0-7, MarkLogic Server would have buffered results in memory. This change allows large result sets to be more easily streamed from XQuery modules.


Due to this change, code that relies on the previous behavior of buffered results from FLWOR expression with only a "let" may experience degraded performance if the results are iterated over multiple times. This is due to the fact that once a streaming result has been exhausted, the query has to be rerun in order to iterate over it again.

Best Practice

Regardless of this change, the best practice is:

  • to treat all query calls as lazily-evaluated expressions and only iterate over them once.
  • If the results need to be iterated multiple times, wrap the search expression in xdmp:eager() or iterate over the results once and assign the results to a new variable.


In 10.0-7 and prior versions, the following expression would be lazily-evaluated and run the search multiple times if the $results variable is iterated over multiple times.

let $_ := xdmp:log("running search")
let $results := cts:search(fn:collection(), cts:word-query("MarkLogic"))

This behavior has not changed in 10.0-7. However, prior to 10.0-7, the following expression would short-circuit the lazy evaluation and buffer all of the results in memory

let $results :=
    let $_ := xdmp:log("running search")
    return cts:search(fn:collection(), cts:word-query("MarkLogic"))

In 10.0-7, this is now consistent with the other form of the expression above and returns an iterator. The search will be run multiple times if the $results variable is iterated over multiple times.

To achieve the buffering behavior in 10.0-7 or later releases, you can wrap cts:search() inside xdmp:eager() as follows

let $results :=
    let $_ := xdmp:log("running search")
    return xdmp:eager(cts:search(fn:collection(), cts:word-query("MarkLogic")))


The xdmp:streamable function was added in MarkLogic 10.0-7 in order to help determine if a variable will stream or not, 

Additional References

For more information about lazy evaluation in MarkLogic, see the following resources

(2 vote(s))
Not helpful

Comments (0)