Utilizing path indexes in the REST API

by Evan Lenz

We've taken a look at a new feature in MarkLogic 6 (path range indexes, part 1 and part 2) and how to use them from within XQuery. Also with this release, it's now possible to write applications using the REST API (or the new Java API) without having to learn XQuery. In this article, I'll give you a taste of the REST API by porting the examples from the last article to pure REST API examples.

The first step to following along is to set up a REST API instance. If you'd like to fully participate, go ahead and do that. I'll wait. This article assumes you'll use the same server (localhost), port (8011), and credentials.

You'll also want to set up your path range index according to the screenshots in the last article, which will result in an int-typed index against the following path: /w:widget/w:part/@count.

Inserting a document using the REST API

Next, we'll insert our sample document:

The REST API, of course, supports document insertion via HTTP PUT. Using the curl utility, we'll insert the above document by running the following command:

To confirm that the document was loaded, GET this URL in your browser: http://localhost:8011/v1/documents?uri=/widget.xml&format=xml

Exposing a path range index to the REST API

Now, let's utilize the path range index. We'll make it available through the /search REST endpoint as a named constraint, as well as through the /values REST endpoint (for retrieving all the index's unique values). To do that, we need to let the REST API instance know about the index by storing some options on the server, which we'll subsequently use in our queries. This is a one-time configuration step requiring the "rest-admin" role.

Uploading the options

We can express options in either XML or JSON. Take a look at the following JSON-based options:

The "constraint" object defines a search constraint named "part-count" that's associated with our server's index, using the JSON syntax for identifying a range index. Similarly, the "values" object defines a set of named values (which we're also naming "part-count"), associated with the same index, using the same syntax.

We can now upload these options to the REST server, giving them a name ("path-example") by running the following command:

To confirm that these options are now available, you can GET them in your browser:

Defining the namespace binding

So that the "w" prefix is understood to map to the "http://example.com/widgets" namespace URI, we need to configure that on the server too. We can do this by POST'ing the following JSON to the /config/namespaces endpoint:

To do that, run the following curl command:

Verifying the configuration

To verify that you've correctly wired together the range index and namespace specification in your REST API instance with the actual range index configured in MarkLogic Server, you can use the /config/indexes endpoint:

If the "complete" key or element says "false", that means the range index is not available on this database, which means you still need to configure it in the admin UI. Otherwise, you'll get an error when you try to use the "part-count" values or constraint.

Running queries against the path index using the REST API

The real fun part comes after we've configured everything. Now we can start querying our data using the path index. To get all the unique values for "part-count", make a GET request to the /values/{name} endpoint:

Note that in each case we need to specify the options by name ("path-example").

To run a search using the "part-count" constraint, we can include it directly in our query string using the name:value constraint syntax:

Since this is a range constraint, we can also perform range queries in the query string. Here we're searching for every document with a part-count greater than 20.

In addition to using the constraint syntax in a search string, you can also utilize the path index constraint in a structured query. For example, the following structured query (shown here in its XML representation) will find all documents that either have a part-count of 30 or are in the "/special-widgets/" directory:

To run the query, you can POST it or include it as the "structuredQuery" parameter in a GET request: http://localhost:8011/v1/search?options=path-example&structuredQuery=%3Cquery...

That concludes our current series on path range indexes! Feel free to reply with any questions you might have.