This chapter describes how to use, write, read, and delete query options. In the MarkLogic XQuery Search API, a query options object is called an options node.
This chapter contains the following sections:
For details on each of the query options, see Appendix: Query Options Reference in the Search Developer's Guide. While there are a large number of options, in order to configure your searches properly and build persistent query options, you will need to familiarize yourself with them.
Query options let you specify a set of options for search and apply them repeatedly to multiple searches. The individual options can specify the following:
Query options can be persistent or dynamic. Persistent query options are stored on the REST Server and referenced by name in future queries. Dynamic query options are options created on a per-request basis. Choosing between the two is a trade off between flexibility and performance: Dynamic query options are the more flexible, but persistent query options usually provide better performance. You can use both persistent and dynamic query options in the same query. Dynamic query options are only available for operations that accept a RawCombinedQueryDefinition
. For details, see Apply Dynamic Query Options to Document Searches.
Use a QueryOptionsManager
object to manage persistent query options and store them on the REST Server. To see individual option values, use the appropriate get()
command on a handle class that implements QueryOptionsReadHandle
.
The persistent query options are the static part of the search, and are generally used for many different queries. For example, you might create persistent query options that define a range contraint on a date range index so that you can facet the results by date.
Additionally, many queries have a component that is constructed dynamically by your Java code. For example, you might change the result page, the query criteria (terms, facet values, and so on), or other dynamic parts of the query. The static and dynamic parts of the query are merged together during a search.
For details on specific query options, see Appendix: Query Options Reference in the Search Developer's Guide. While there are a large number of options, in order to configure your searches properly, you will need to familiarize yourself with them.
For additional examples, see Query Options Examples in the Search Developer's Guide.
The MarkLogic Java API comes with predefined persistent query options called default
. It acts just like any other options and is used if options are not specified elsewhere. You can read it into a handle, change values, and write it back out, where it will still be used as the default query options. While changing its values should not be done casually, this can be very useful if your site needs different default behaviors.
The default options are selected for optimal performance; searches run unfiltered, and document quality is not taken into consideration during scoring. If you install different default options, consider including the following options unless your application requires filtering or the use of document quality.
<options xmlns="http://marklogic.com/appservices/search"> <search_option>unfiltered</search-option> <quality-weight>0</quality-weight> </options>
If you delete default
, the server will fall back to its own defaults.
Interactions with the database are done via a manager object, in this case QueryOptionsManager
. Use com.marklogic.client.admin.QueryOptionsManager
to manage persistent query options that are stored on the REST server. Since query options are associated with the REST server configuration, to create a QueryOptionsManager
you call ServerConfigManager.newQueryOptionsManager()
.
As with all operations on ServerConfigManager
, an application must authenticate as rest-admin
. Note that any application that authenticates as rest-reader
and rest-writer
can use query options, but to write or delete them from the server requires rest-admin
.
// create a manager for writing, reading, and deleting query options QueryOptionsManager qoManager= client.newServerConfigManager().newQueryOptionsManager();
The simplest QueryOptions
operation is deleting a stored one:
qoManager.deleteOptions("myqueryoptions");
To read query options from the database, use a handle object of a class that implements QueryOptionsReadHandle
. To write query options to the database, use a handle object of a class that implements QueryOptionsWriteHandle
. The API includes several handle classes that implement these interfaces, including StringHandle
, BytesHandle
, DOMHandle
, and JacksonHandle
. These interfaces allow you to work with query options as raw strings, XML, and JSON.
The following example reads in the options configuration called myqueryoptions
from the server, then writes it out again.
// read a query option configuration from the database // qoHandle now contains the query option // "myqueryoptions" DOMHandle qoHandle = qoManager.readOptions("myqueryoptions", new DOMHandle()); // write the query option to the database qoManager.writeOptions("myqueryoptions", qoHandle);
You can get a list of all named QueryOptions
from the server via the QueryOptionsListHandle
object:
QueryManager queryMgr = dbclient.newQueryManager(); QueryOptionsListHandle qolHandle = queryMgr.optionsList(new QueryOptionsListHandle()); Set<String> results = qolHandle.getValuesMap().keySet();
You can customize a query with query options in the following ways:
// Create a string query that uses persistent query options QueryManager qMgr = new QueryManager(); StringQueryDefinition qDef = qMgr.newStringDefinition("myoptions"); ... qMgr.search(qDef, resultsHandle);
You can use both persistent and dynamic query options in the same search by including a query options name when constructing a combined query (RawCombinedQueryDefinition
).
Persistent query options must be stored on the REST server before you can use them in a search. For details, see Using QueryOptionsManager To Delete, Write, and Read Options.
To construct persistent query options, use a handle class that implements QueryOptionsWriteHandle
, such as StringHandle
or DOMHandle
. Using a handle, you can create query options directly in XML or JSON; for details, see Creating Persistent Query Options From Raw JSON or XML.
To construct dynamic query options, use a handle that implements StructureWriteHandle
, such as StringHandle
or DOMHandle
to create a combined query that includes an options component, then associate the handle with a RawCombinedQueryDefinition
. For details, see Apply Dynamic Query Options to Document Searches.
To create persistent query options from a raw XML or JSON representation, use any handle class that implements com.marklogic.client.io.marker.QueryOptionsWriteHandle
. Follow this procedure to create persistent query options using a handle:
String xmlOptions = "<search:options "+ "xmlns:search='http://marklogic.com/appservices/search'>"+ "<search:constraint name='industry'>"+ "<search:value>"+ "<search:element name='industry' ns=''/>"+ "</search:value>"+ "</search:constraint>"+ "</search:options>";
QueryOptionsWriteHandle
and associate your options with the handle. Set the content format type appropriately. For example:// For XML options StringHandle writeHandle = new StringHandle(xmlOptions).withFormat(Format.XML); // For JSON options StringHandle writeHandle = new StringHandle(jsonOptions).withFormat(Format.JSON);
QueryOptionsManager.writeOptions
. For example:optionsMgr.writeOptions(optionsName, writeHandle);
For a complete example, see com.marklogic.client.example.cookbook.QueryOptions
in the following directory of the Java API distribution:
example/com/marklogic/client/example/cookbook
The Java API includes QueryOptionsWriteHandle
implementations that support constructing query options as XML or JSON using several alternatives to String
. These alternatives include reading from a file (FileHandle
) or stream (InputStreamHandle
), and popular abstractions, such as DOM, DOM4J, and JDOM. For details, see the Java API JavaDoc.
You can use any handle that implements QueryOptionsReadHandle
to fetch previously persisted query options from the REST server. The following example fetches the JSON representation of query options into a String
object:
StringHandle jsonStringHandle = new StringHandle(); jsonStringHandle.setFormat(Format.JSON); qoManager.readOptions("jsonoptions", jsonStringHandle);
Query options can be complex. By default, the server validates query options before writing them out to a database. This takes a small amount of time, but because the query options are usually created once and then persisted, it does not really make a difference.
If you do try to write out an invalid query options and validation is enabled (which is the default), you get a 400
error from the server and a FailedRequestException
thrown.
If you want to turn validation off, you can do so by calling the following right after you create your ServerConfigurationManager
object:
ServerConfigurationManager.setQueryOptionValidation(false)
Note that if validation is disabled and you have query options that turn out to be invalid, your searches will still run, but any invalid options will be ignored. For example, if you define an invalid constraint and then try to use it in a search, the search will run, but the constraint will not be used. The search results will contain a warning in cases where a constraint is not used. You can access those warnings via SearchHandle.getWarnings()
.