MarkLogic Server allows you to access range indexes in a
cts:query expression to constrain a search by a range of values in an element or attribute. This chapter describes some details about these range queries and includes the following sections:
Range queries are designed to constrain searches on ranges of a value. For example, if you want to find all articles that were published in 2005, and if your content has an element (or an attribute or a property) named
PUBLISHDATE with type
xs:date, you can create a range index on the element
PUBLISHDATE, then specify in a search that you want all articles with a
PUBLISHDATE greater than December 31, 2004 and less than January 1, 2006. Because that element has a range index, MarkLogic Server can resolve the query extremely efficiently.
Because you can create range indexes on a wide variety of XML datatypes, there is a lot of flexibility in the types of content with which you can use range queries to constrain searches. In general, if you need to constrain on a value, it is possible to create a range index and use range queries to express the ranges in which you want to constrain the results.
Keep in mind the following requirements for using range queries in your cts:search operations:
Because range queries require range indexes, keep in mind that range indexes take up space, add to memory usage on the machine(s) in which MarkLogic Server runs, and increase loading/reindexing time. As such, they are not exactly 'free', although, particularly if you have a relatively small number of them, they will not use a huge amount of resources. The amount of resources used depends a lot on the content; how many documents have the elements and/or attributes specified, how often do those elements/attributes appear in the content, how large is the content set, and so on. As with many performance improvements, there are trade-offs to analyze, and the best way to analyze the impact is to experiment and see if the cost is worth the performance improvement. For details about range indexes and procedures for creating them, see the Range Indexes and Lexicons chapter in the Administrator's Guide.
Using range queries in
cts:query expressions can produce faster performance than using XPath predicates. Range indexes are in-memory structures, and because range indexes are required for range queries, they are usually very fast. There is no requirement for the range index when specifying an XPath predicate, and it is therefore possible to specify a predicate that might need to scan a large number of fragments, which could take considerable time. Additionally, because range queries are
cts:query objects, you can use registered queries to pre-compile them, adding more performance advantages.
There are also coding advantages to range queries over XPath predicates. Because range queries are leaf-level
cts:query constructors, they can be combined with other constructors (including other range query constructors) to form complex expressions. It is fairly easy to write XQuery code that takes user input from a form (from drop-down lists, text boxes, radio buttons, and so on) and use that user input to generate extremely complex
cts:query expressions. It is very difficult to do that with XPath expressions. For details on
cts:query expressions, see Composing cts:query Expressions.
Each API takes QNames, the type of operator (for example, >=, <=, and so on), values, and a collation as inputs. For details of these APIs and for their signatures, see the MarkLogic XQuery and XSLT Function Reference.
<root> <entry> <date>2007-01-01</date> <info>Some information.</info> </entry> <entry> <date>2006-06-23</date> <info>Some other information.</info> </entry> <entry> <date>1971-12-23</date> <info>Some different information.</info> </entry> </root>
Assume you have defined an element range index of type
xs:date on the QName
date (note that you must either load the document after defining the range index or complete a reindex of the database after defining the range index).
You can now issue queries using the cts:element-range-query constructor. The following query searches the
entry element of the document
/dates.xml for entries that occurred on or before January 1, 2000.
cts:search(doc("/dates.xml")/root/entry, cts:element-range-query(xs:QName("date"), "<=", xs:date("2000-01-01") ) )
The following query uses a cts:and-query to combine two date ranges, dates after January 1, 2006 and dates before January 1, 2008.
cts:search(doc("/dates.xml")/root/entry, cts:and-query(( cts:element-range-query(xs:QName("date"), ">", xs:date("2006-01-01") ), cts:element-range-query(xs:QName("date"), "<", xs:date("2008-01-01") ) )) )