Java Application Developer's Guide (PDF)

Java Application Developer's Guide — Chapter 6

« Previous chapter
Next chapter »

Query Options

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.

Using Query Options

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:

  • Define constraints that do not require indexes, such as word, value and element constraints.
  • Define constraints that do require indexes, such as collection, field-value, and other range constraints.
  • Control search characteristics such as case sensitivity and ordering.
  • Extend the search grammar.
  • Customize query results including pagination, snippeting, and filtering.

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 constraint 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.

Default Query Options

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>

The equivalent in JSON:

{"options":{
            "search-option": "unfiltered",
            "quality-weight": "0"
    }
}

If you delete default, the server will fall back to its own defaults.

Using QueryOptionsManager To Delete, Write, and Read Options

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());

//Or the equivalent with a JacksonHandle
JacksonHandle qoHandle =
    qoManager.readOptions("myqueryoptions", new JacksonHandle());

// 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();

Using Query Options With Search

You can customize a query with query options in the following ways:

  • Create persistent query options, save them to the REST server with an associated name, and then reference them by name when you construct a query. To use the default query options, omit an options name when you construct the query. The following example creates a string query that uses the options stored as myoptions:
    // Create a string query that uses persistent query options
    QueryManager qMgr = new QueryManager();
    StringQueryDefinition qDef = qMgr.newStringDefinition("myoptions");
    ...
    qMgr.search(qDef, resultsHandle);
  • Embed dynamic query options in a combined query definition.

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.

Creating Persistent Query Options From Raw JSON or XML

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:

  1. Create a JSON or XML representation of the query options, using the tools of your choice. The following example uses a String representation:
    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>";
    
    String jsonOptions =
            "{\"search\":{" +
                    "   \"constraint\": {" +
                    "      \"name\": \"industry\"," +
                    "      \"value\": {" +
                    "         \"element\": {" +
                    "            \"name\": \"industry\"," +
                    "            \"ns\": \"\"" +
                    "         }" +
                    "      }" +
                    "   }" +
                    "}" +
                "}";
  2. Create a handle that implements 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);
  3. Save the options to the REST server using 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);

Validating Query Options With setQueryOptionValidation()

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().

« Previous chapter
Next chapter »
Powered by MarkLogic Server | Terms of Use | Privacy Policy