I have the impression that the XQuery and the Server-side JavaScript APIs in MarkLogic are largely equivalent. But there seems to be a big difference in cts:search
vs cts.search
. In cts:search
, I am able to specify an element to be searched and returned. For example, I can retrieve all recipes using cinnaomon as ingredient from a recipe book:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
Whereas cts.search
doesn't accept a path expression and will return the whole recipe book document:
cts.search(cts.elementWordQuery(xs.QName('ingredients'), 'cinnamon'))
The same question has been asked in MarkLogic mailing list but I don't see an answer there: https://developer.marklogic.com/pipermail/general/2015-March/016508.html
Below is a minimal example:
<book>
<recipe>
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
<recipe>
<ingredients>sugar, peppermint</ingredients>
<instruction/>
</recipe>
<recipe>
<ingredients>coconut oil</ingredients>
<instruction/>
</recipe>
</book>
The xquery would be:
cts:search(//recipe, cts:element-word-query(xs:QName('ingredients'), 'cinnamon'))
and the response:
<recipe>
<ingredients>cinnamon, peppermint</ingredients>
<instruction></instruction>
</recipe>
Building up on DALDEI's answer you can use the search api to return only recipe elements:
const search = require('/MarkLogic/appservices/search/search');
let options = fn.head(xdmp.unquote(`
<options xmlns="http://marklogic.com/appservices/search">
<return-results>true</return-results>
<searchable-expression>//recipe</searchable-expression>
<extract-document-data>all</extract-document-data>
<additional-query>
<cts:element-word-query xmlns:cts="http://marklogic.com/cts">
<cts:element>ingredients</cts:element>
<cts:text xml:lang="en">cinnamon</cts:text>
</cts:element-word-query>
</additional-query>
</options>`)).root;
search.search("", options) // returns a Sequence of search:response
.toArray()[0] // get the first result
.getElementsByTagName("recipe") // find all recipe elements
This code returns a NodeList of recipe elements. The result for your provided book would be this single element node:
<recipe xmlns:search="http://marklogic.com/appservices/search">
<ingredients>cinnamon, peppermint</ingredients>
<instruction/>
</recipe>
This is not really a nice solution (in terms of quick and easy) but it might work as a workaround.
I also tried using the jsearch functions but didn't find a way to pass a searchable-expression
parameter. I might have missed that because I have not used this alot yet.
Further readings: