Searching Content

The JCR provides multiple ways to discover content. The repository can be browsed through the node API by, for example, the application of the visitor pattern. The JCR further sets for a variety of ways of searching content. For one, all content can be discovered through XPath, which is a mandatory feature for all repository implementations. Optionally, the repository may allow a special SQL-like syntax for searching content. JSR283 JSR283 deprecates the JSR170 SQL syntax and replaces it with JCR-SQL2. It further introduces a third query mechanism, JCR-JQOM which expresses the query as a tree of java objects.

Query Specification

While queries can be written in a variety of ways (see above), every query consists of the following elements:

  • Type constraints which limit the query results to a particular type of node. This can be used to query for primary node types as well as mixin types.
  • Property constraints which limit the result set to nodes which contain a specific property as well as properties with specific values.
  • Path constrains constrain the query result to a certain path in the repository.
  • An ordering specifier which defines the order in which nodes are returned by (for example alphabetical by node name).
  • Column specifiers which determines field names which are to be returned to be viewed in the row/column format

Executing Queries

All queries are submitted through the QueryManager, which can be obtained from the workspace via the method Workspace.getQueryManager(). It allows the programmer to create new queries via the call QueryManager.createQuery(String query, String queryLanguage) where the query language parameter is one of Query.SQL or Query.XPATH. This method call returns an object of type Query which can then be executed.

Persistent Queries

Queries can be made persistent, i.e. stored as a node in the repository by calling Query.storeAsNode(String path) which stores the query as a node of type nt:query. Such a persistent query can later be retrieved via QueryManager.getQuery(Node node).

Accessing Query Results

The query results can be presented in two different ways. For one, an iterator over all resulting nodes or as a table in which each row presents a resulting node and the columns select properties of the matching nodes. The following code outlines the simplest way of viewing a result set by iterating over the nodes:

QueryResult queryResult = query.execute();

NodeIterator nodes = queryResult.getNodes(); 

// now iterate over the nodes

The following example utilizes a row-based approach to visualize the query result:

String[] headers = queryResult.getColumnNames();
for (int i = 0; i < headers.length; i++) {
  System.out.printf("%20s | ", headers[i]);
}
System.out.println();

for (RowIterator rowIterator = queryResult.getRows();
                                rowIterator.hasNext();) {

  Row row = rowIterator.nextRow();
  Value[] values = row.getValues();
  for (int i = 0; i < values.length; i++) {
    System.out.printf("%20s | ", values[i].getString());
  }

System.out.println();
}

XPath Search

The XPath search is executed against the document view XML format (see section XML Import and Export). Let’s explore this by an example. The following code creates three nodes underneath the root node:

Node folder = root.addNode("folder", "samples:folder");

Node node = folder.addNode("node", "samples:teaser");

node.setProperty("samples:title", "first title");

Node node2 = folder.addNode("node", "samples:teaser");

node2.setProperty("samples:title", "second title");

// export to XML
session.exportDocumentView("/", System.out, true, false);

This translates to the following document view XML (the namespace declarations have been omitted for brevity’s sake):


To create a query which returns all nodes underneath node folder which have a property named samples:title with the value second title, the following XPATH query can be constructed:

QueryManager queryManager = workspace.getQueryManager();

Query query = queryManager.createQuery(
      "/jcr:root/folder/*[@samples:title='second title']", Query.XPATH);
QueryResult queryResult = query.execute();

for (NodeIterator nodes = queryResult.getNodes(); nodes.hasNext();) {
  Node n = nodes.nextNode();
  System.out.println(n.getPath());
}

JCR-SQL

While the XPath notation is very powerful, many developers find it hard to adopt (unless of course they’re XML experts). The SQL notation represents a powerful alternative. However, it is deprecated and replaced by JCR-SQL2 in JSR283. The JCR-SQL equivalent of the above XPath query is:

Query query = queryManager.createQuery("select * from samples:teaser where
                 samples:title='second title'", Query.SQL);

Pages: 1 2 3 4 5 6 7 8 9 10 11