1

In MarkLogic, is there a way to construct a CTS query from a JSON serialization thereof in XQuery (without having to invoke JavaScript)? I only see a JSON example using JavaScript (and XML using XQuery) but not a JSON example using XQuery here: https://docs.marklogic.com/guide/search-dev/cts_query#id_17645

I successfully got the desired result when I ran the following code, but I would like to do this in just XQuery instead:

let $script := 'var json; cts.query(fn.head(xdmp.fromJsonString(json)))'
return
  xdmp:javascript-eval($script, map:entry("json", '{"wordQuery":{"text":["hello"], "options":["lang=en"]}}'))

Can it be done?

Evan Lenz
  • 4,086
  • 1
  • 19
  • 18

2 Answers2

2
  • xdmp:from-json-string() can be used to parse a JSON string. It will construct a JSON object (which is basically a specialized map).
  • You can convert that JSON object into a JSON document using xdmp:to-json().
  • select the child JSON object-node() from the returned document-object, and send to cts:query() to parse it into a cts:query

Like this:

xdmp:from-json-string('{"wordQuery":{"text":["hello"], "options":["lang=en"]}}') 
  ! xdmp:to-json(.)/object-node() 
  ! cts:query(.)
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • 1
    Thanks Mads! That's doubly tricky. First the distinction between a JSON object and a JSON document. Then the need to grab the object-node() child of the document node. I had gotten so far as to use cts:query(xdmp:from-json-string($json)), but I was missing a couple more steps (that didn't apply in the JavaScript version). Thank you again! Works perfectly. – Evan Lenz Aug 27 '22 at 00:11
  • Agreed, it's sort of convoluted and the names of the functions aren't always clear what is being constructed and returned. It took me a while to figure it out myself! – Mads Hansen Aug 27 '22 at 00:16
  • Yes, I didn't even mention the confusing names. Thanks for your kindness & understanding. – Evan Lenz Aug 27 '22 at 00:19
1

A shorter and easier method is to use xdmp:unquote()

xdmp:unquote('{"wordQuery":{"text":["hello"], "options":["lang=en"]}}')/object-node()  
  => cts:query()
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • 1
    Ooh, I like that. It also dodges those confusingly-named functions. Only difference is I'm still using the mapping operator: `$json-string ! xdmp:unquote(.)/object-node() ! cts:query(.)` – Evan Lenz Aug 29 '22 at 18:45