Search code examples
xquerymarklogic

How can I get cts:values for elements with special attribute value


I have a document

    <document>
     <category selected="true">a</category>
     <category>b</category>
     <category selected="true">c</category>
    </document>

How can I get just the values from the category[@selected eq 'true'] ? I was trying to use next:

    cts:element-values(xs:QName("category"), (), (), cts:element-attribute-value-query(xs:QName("category"), xs:QName("selected"), "true"))

but I understand that in this case I will get all the categories.


Solution

  • Your cts:element-attribute-value-query() is matching all documents that have a category element with a selected attribute of true. Then your cts:element-values() returns the distinct values of all of the category elements in each of those documents, regardless of whether the category has a @selected = 'true' attribute.

    Presumably you want to get the values out of many, perhaps hundreds of millions of documents, that are similarly structured, and not just this one. For one document, XPath would be fine. Across an entire database, however, you’ll need a range index to do this efficiently. Range indexes, as their name implies, keep an ordered set of values and references to the documents in which they’re found in memory. This makes getting distinct values or calculations across ranges of values very efficient.

    With your range index you can use cts:values() to get values straight out of the indexes without having to read the documents themselves. Given your document structure, you’ll need a path range index to differentiate selected categories from unselected ones. Thus you’d create a path range index on category[@selected = 'true'] and then call cts:values(cts:path-reference("category[@selected = 'true']")). cts:values() can also take a cts:query as its fourth parameter to limit the domain of documents over which the values are matched.