1
votes

Hi I am new to MarkLogic and while reading ML documentation i found that Performance of Executing CTS Query is Better than Executing Plain XQuery.

Requirement : I need to Convert Below XQuery to CTS Query to Perform Search for XPath and its Values and also i don't want to create Path Range Index for XPath because I am getting Xpath Dynamically.

for $document in collection()[/tXML/Message/TEST/TEST1/TESTID="10"]
return
    (
        if(fn:not(fn:empty($document/tXML/Message/TEST/TESTID))) then $document/tXML/Message/TEST/TESTID else "NULL",
        if(fn:not(fn:empty($document/tXML/Message/TEST/TESTType))) then $document/tXML/Message/TEST/TESTType else "NULL",
        if(fn:not(fn:empty($document/tXML/Message/TEST/TESTStatus))) then $document/tXML/Message/TEST/TESTStatus else "NULL"
    )

So Please Help me to find out whether it is possible to form CTS Query for Above XQuery.

1
Can you elaborate a little on the getting XPath Dynamically bit? Is it passed in as string or such? Beware of code injection.. - grtjn
I have a function which take xpath and its value as parameter so this case i am getting /tXML/Message/TEST/TEST1/TESTID="10" from user and next time user can send another xpath so i mentioned it as "getting XPath Dynamically" - Shivling Bhandare
So you need a function that parses an xpath and generates an equivalent cts query. Is the user passing in arbitrary xpath, or is it always a straight element path like your example? The potential complexity of the xpath will radically affect how hard a problem you have. - BenW
Thxs @BenW for adding comment... Right now I need exactly equivalent CTS query for above Xquery - Shivling Bhandare

1 Answers

2
votes

If you can't add path indexes, but the entire path is important (so you can't just use just a cts:element-value-query(xs:QName('TESTID'), "10")), then you can use an element query stack like this

let $query := 
    cts:element-query(xs:QName('tXML'),
        cts:element-query(xs:QName('Message'),
            cts:element-query(xs:QName('TEST'),
                cts:element-query(xs:QName('TEST1'),
                    cts:element-value-query(xs:QName('TESTID'), "10")))))

As per the element-query docs, you'll want to have the "word position" and "element word position" indexes enabled.

Processing the result of the search isn't any different.

 for $document in cts:search(collection(), $query)
 return (
    if(fn:not(fn:empty($document/tXML/Message/TEST/TESTID))) then $document/tXML/Message/TEST/TESTID else "NULL",
    if(fn:not(fn:empty($document/tXML/Message/TEST/TESTType))) then $document/tXML/Message/TEST/TESTType else "NULL",
    if(fn:not(fn:empty($document/tXML/Message/TEST/TESTStatus))) then $document/tXML/Message/TEST/TESTStatus else "NULL"
)