Search code examples
oraclemarklogic

Marklogic how to construct a cts query


I have a Oracle query and would like to transform into Marklogic cts query. It looks like Marklogic CTS doesn't allow to have "and-query" inside of "and-query". I am not sure how Marklogic works. Thanks in advance.

Where clause query:

where (collection = "TRBA" AND fulltext = 1 
       AND (dnta = "Briefing" OR dnta = "Conference" OR snta = "Workshop"
            OR snta = "Published in" AND (snta = "this article" OR dnta = "Journal")
      )
      AND (cand IN ("Research","Development Center") OR scn IN("424778","98814","393825")) 

Translate into Marklogic:

let $uris:= cts:uris(
                     (),
                     (),
                     cts:and-query((
                          cts:collection-query("/dbs/"TRBA"),
                          cts:element-value-query(xs:QName("meta:FullTextExists"),"1"),
                          cts:field-word-query("dnta",("briefing","conference")),

                         cts:or-query((
                              cts:element-word-query(xs:QName("meta:snta"),("this article")),
                              cts:field-word-query("dnta",("Journal")),

                        cts:and-query((
                             cts:or-query((
                                   cts:field-word-query("cand", ("Research","Development Center"))
                                   cts:field-word-query("scn",("424778","98814","393825")) 
                             ))
                          ))(:inside and-query:)
                        ))(:or-query:)
                     ))(:outside and-query:)

 return fn:doc($uris)

Solution

    1. There are basic syntax errors in your code above: missing parens, extra double quotes
    2. I don't think you want word query as the translation for "="; word query just says that word appears somewhere in the field in question; I would think that would be a value query instead.
    3. You might want to take a look at cts:parse which takes a string with ANDs and ORs etc. plus bindings for fields and parses a query string into a cts:query

    That said, if you assume the AND mixed in with the ORs binds to the closest clause, i.e. as parenthesized so:

    (collection = "TRBA" AND
     fulltext = 1  AND
     (dnta = "Briefing" OR
      dnta = "Conference" OR
      snta = "Workshop" OR
      (snta = "Published in" AND (snta = "this article" OR dnta = "Journal"))
     ) AND
     (cand IN ("Research","Development Center") OR
      scn IN ("424778","98814","393825"))
    

    then I would translate this something like this:

    cts:and-query((
      cts:collection-query("/dbs/TRBA"),
      cts:element-value-query(xs:QName("meta:FullTextExists"),"1"),
      cts:or-query((
        cts:field-value-query("dnta",("Briefing","Conference")),
        cts:field-value-query("snta","Workshop"),
        cts:and-query((
          cts:field-value-query("snta","Published in"),
          cts:or-query((
            cts:field-value-query("snta","this article"),
            cts:field-value-query("dnta","Journal")
          ))
        ))
      )),
      cts:or-query((
        cts:field-value-query("cand",("Research","Development Center")),
        cts:field-value-query("scn",("424778","98814","392825"))
      ))
    ))
    

    It is a pretty direct mapping.