Problem

You want to find out the values in an element along with their counts.

Solution

Applies to MarkLogic versions 7+

xquery version "1.0-ml";

let $ref := cts:element-reference(xs:QName("value"))
for $value in cts:values($ref)
return <value count="{cts:frequency($value)}">{$value}</value>

This produces output like:

<value count="151">a</value>
<value count="200">b</value>
<value count="162">c</value>
<value count="168">d</value>
<value count="162">e</value>
<value count="157">f</value>

Required Indexes:

  • range index on “value”

Discussion

Whether exploring data, or constructing a facet in a custom constraint, sometimes you want to see what values are contained in an element (or attribute, or field), and how many of each of them you have. Developers who are new to MarkLogic often turn to fn:distinct-values(), like this:

fn:distict-values(/content/author/full-name)

While this approach will work fine for small numbers of values, it doesn’t scale. As written, MarkLogic will retrieve all fragments that the /content/author/full-name path matches, put the full-name elements into a sequence, and pass that to fn:distinct-values(). Because distinct-values expects a sequence of strings, each element is converted to a string. The function will then loop through each string it was given in order to find the unique values.

Consider a database that has 1,000 documents, but just 10 distinct values. Even such a small example is enough to illustrate how much effort MarkLogic has to waste, loading all 1,000 fragments to get just those 10 values. To see how many fragments MarkLogic would need to load to answer this query on your data, run this in Query Console: (substituting your XPath)

xdmp:plan(/content/author/full-name)

Conversely, if a range index is available, then the work has already been done. An element range index on full-name, or a path range index on /content/author/full-name, will have a list of distinct values, along with identifiers of fragments that hold the values. By calling cts:values(), we directly access the index and don’t need to load any of the fragments.

Learn More

Application Developer's Guide

Read the methodologies, concepts, and use cases related to application development in MarkLogic Server, with additional resources.

MarkLogic Developer Learning Track

Want to build that awesome app? Get off the ground quickly with the developer track, with instructor-led and self-paced courses.

Getting Started Video Tutorials for Developers

This series of short videos tutorials takes developers who are new to MarkLogic from download to data hub, fast.

This website uses cookies.

By continuing to use this website you are giving consent to cookies being used in accordance with the MarkLogic Privacy Statement.