«»

JCR Deep Dive

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:

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

«»

Comments

9 Responses to “JCR Deep Dive”

  1. Duncan Reade on January 30th, 2009 8:54 am

    First, thank you for providing this very informative site. And Secondly, just in case it has not been brought to your attention: the URI links to the http://www.jcp.org/ site are out of date (used in section 3. Defining Content).

    Regards
    Duncan Reade

  2. Thomas Einwaller on March 13th, 2009 3:20 am

    Thanks for that great post.

    It seems node type folder is missing?

  3. Yasser on June 12th, 2009 7:06 am

    Really good post.. thanks for the effort

  4. Bruno Dusausoy on October 22nd, 2009 6:50 am

    Hi, great article.
    But as Thomas said previously, it seems you forgot to put the node type “samples:folder” definition. It seems it’s a copy/paste of the “samples:content” definition instead.

  5. Patrick van Kann on October 19th, 2010 11:58 am

    Really great article.

    With regards to the missing definition for samples:folder, I believe the below works.

    [samples:folder] > samples:content
    // accept any subnodes of type samples:content
    + * (samples:content) multiple

    I adapted this from the example in the CND in a nutshell section of this blog.

  6. Jochen on October 20th, 2010 10:44 am

    Thanks! I need to spend some time updating my blog at some point :-)

  7. Serge on October 28th, 2010 12:54 pm

    Great content. Are there some good interative builder for CND Types ? Would be interesting links

  8. Jochen on October 28th, 2010 1:16 pm

    Building an interactive builder shouldn’t be that hard. Back when I worked for CoreMedia we had a tool that would take the XMI from any old UML tool and XSLT’ed it to a content definition file. Wasn’t CND but XML, but same idea.

  9. Confluence: MIS I. T. Development on September 20th, 2011 7:45 am

    Java Content Repository Deep Dive…

    I found an interesting “article” online about Java Content Repositories (JCR). I’m going to look into this further because it may be useful as a replacement to our current JPA workflow. JCR supports many features that should be useful,……

Leave a Reply




XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

-->