Tuesday, 13 July 2010

MarkLogic cts:query serialization

If you work with MarkLogic you've surely come across cts functions (Built-In: Search), cts:query, and its closest counterparts.

One useful feature available in recent releases is the serialization of cts queries, which allows for the conversion of cts:query types to xml fragments, and the other way round.

If you take a look at the code below, you'll notice the local:mySearch() function which takes a cts:query as it's only parameter. You'll also note cts:search() is used inside this function and references the $query parameter abstracting the query executed by cts:search(). Most interestingly you'll also find a conditional statement invoking an xpath on the $query variable. "But the parameter is strongly typed to cts:query!" . . . you ask. Well that's because it is possible to serialize what would otherwise be "cts:element-value-query(xs:QName("filename"), "myFile", ("lang=en"), 1)" to xml, just by embedding the query in a parent element.

let $query as element(query) := element query {$query}

It is equally possible to do the reverse operation, simply by invoking an xpath returning cts elements in your fragment, wrapped in a cts:query() function.


This feature also allows for cts queries to be built dynamically as xml fragments rather than concatenated strings.

xquery version '1.0-ml';

declare function local:mySearch($query as cts:query) as element(response)
let $query as element(query) := element query {$query}
let $searchResults as element(record)* := cts:search(/record, cts:query($query/*))

element response
element results {
if($query/cts:element-value-query/cts:element/text() eq "filename")
then $searchResults//element1
else $searchResults//element2

declare function local:searchByFilename($filename as xs:string) as element(response)
{local:mySearch(cts:element-value-query(xs:QName("filename"), $filename))};

declare function local:searchByVolume($volume as xs:string) as element(response)
{local:mySearch(cts:element-value-query(xs:QName("volume"), $volume))};



<cts:element-value-query xmlns:cts="http://marklogic.com/cts">
<cts:text xml:lang="en">myfile</cts:text>
<query>cts:element-value-query(xs:QName("filename"), "myfile", ("lang=en"), 1)</query>
<element1>some content</element1>
<element1>some other content</element1>

No comments:

Post a Comment