What is the difference between cts:search and cts:element-attribute-values?

1.3k Views Asked by At

I can't understand deference between cts:search and cts:element-attribute-values. I can get the same result with both these functions. What is the best resolve?

cts:search(/t:ancestors-list/t:concept/t:concept-ancestor, cts:element-value-query(xs:QName("t:concept-ancestor"), $concept/id))/@subject

or

cts:element-attribute-values(
  xs:QName("t:concept-ancestor"),
  xs:QName("subject"),
  (),
  ("collation=http://marklogic.com/collation/codepoint"),
  cts:element-value-query(
    xs:QName("t:concept-ancestor"),
    $concept/id
  )
)

ar:concept-ancestor is the element range index and element attribute range index.

And xml structure like this

<t:ancestors-list xmlns:ar="http://test.com">
    <t:concept subject="http://test.com/concept#1c5cd7082ac908c62e9176770ae0fb53">
        <t:concept-ancestor subject="http://test.com/concept#1c5cd7082ac908c62e9176770ae0fb53">4a1f650290103d39863bf7bc22ef18aa</t:concept-ancestor>
    </t:concept>
    <t:concept subject="http://test.com/concept#05b707457f79f42c93bf778915e4a589">
        <t:concept-ancestor subject="http://test.com/concept#05b707457f79f42c93bf778915e4a589">4a1f650290103d39863bf7bc22ef18aa</t:concept-ancestor>
        <t:concept-ancestor subject="http://test.com/concept#05b707457f79f42c93bf778915e4a589">1c5cd7082ac908c62e9176770ae0fb53</t:concept-ancestor>
    </t:concept>
    ...
</t:ancestors-list>

Thank you!

2

There are 2 best solutions below

3
On

cts:element-attribute-values requires an element-attribute range index be configured on the values you're querying, and it only returns an atomic type (xs:anyAtomicType*). cts:search returns document nodes, and no indexes are required for cts:element-value-query.

If you only need the values (not XML) and you already have an index, then the cts:element-attribute-values query will be faster.

0
On

The fundamental difference is that cts:search returns a sequence of nodes within which the cts:element-value-query is satisfied, while the cts:element-attribute-valuesfunction returns a stream of the actual attribute values that are defined in your index (where the values are further limited by the cts:element-value-query that you pass to the function).

I can think of several possible reasons for the difference in speed, but this seems to me to be the key:

The cts:search operation has to load and return to you a sequence of concept:ancestor nodes that satisfy the search criteria. The cts:element-attribute-values function call returns a stream of values.

Loading and sending a sequence of nodes is going to be more time- and memory-expensive than giving you a stream of atomic values. A sequence (whether it's of nodes() or atomic values) will get fully loaded into memory before it is returned to you, while a stream of atomic values is lazy-loading, so that it doesn't (necessarily) store all the values in memory at once.

(I just learned about the sequence/stream distinction, and the cts:element-values and cts:element-attribute-valuesfunctions from a just-added post on the MarkLogic Community Blog: Result Streams from Range Indexes.)

The bottom line, though, in choosing between the two approaches has already been suggested by wst:

If you only need the values (not XML) and you already have an index, then the cts:element-attribute-values query will be faster.