Introduction to Jahia JCR Query Languages

Apr 19, 2012
Daniel Ovalle

When you come to Jahia xCM and start working on a website you will find that one of the core technologies behind the CMS is the Apache Jackrabbit project. This is the most mature implementation of the JCR specification available in the open source context market.

If you want to achieve good results with the functionalities implemented on your Jahia projects, then you will need to use the JCR API related features of the CMS. This will let you build custom navigation, content lists and solve complex requirements that demand advanced management of the project content.

What's JCR?

If you're unfamiliar with JCR, a good place to find our more is the Wikipedia page. Here you'll learn that JCR "is a specification for a Java platform application programming interface (API) to access content repositories in a uniform manner1". On this page, along with other information available online, you will find definitions for this 'specification' like:  content database, content relational database, and some people even associate a JCR implementation with a kind of graph database.

There is another definition available for JCR that is not covered in this post, but is still important in keeping with the Apache Jackrabbit definition: "A content repository is a hierarchical content store with support for structured and unstructured content, full text search, versioning, transactions, observation, and more."

Here, I'll focus on one part  of this technical specification (JCR specification JCR-283) : queries. More specifically, queries supported in Jahia xCM.

Since Jahia xCM is built over the Apache Jackrabbit project, most of the features of this implementation API are available on Jahia. There is one exception about the support of XPATH as a valid query language used with the JCR repository: the technical specification deprecated its use but Jahia xCM still supports it.

Supported Query languages

Well lets start listing the supported query languages of the JCR specification and some key concepts.

  • Abstract Query Model: This is the core implementation of the logic that brings to the repository the "queries" as a feature. This means all the queries supported by the JCR implementation will be processed here no matter what query language is used.
  • JCR-SQL2: This query language lets the users (developers) write query sentences similar to SQL language to build the queries over the JCR repository content nodes.
  • JCR Java Query Object Model (JCR-JQOM): This is an API that lets developers to build the queries into Java code and exposes the results as objects trees. If you are familia with the JPA specification for persistence, this will be more like a Object Query Language.

To illustrate a little about each of the languages lets see how a general query is structured on each one:

JCR-SQL2

'SELECT' columns
'FROM' Source
['WHERE' Constraint]
['ORDER BY' orderings]

JCR-JQOM

QueryObjectModel obj = QueryObjectModelFactory.createQuery(
    Source source,
    Constraint constraint,
    Ordering[] orderings,
    Column[] columns);

Building Queries

As I mentioned before, JCR repositories are designed to store content. This content is stored into the repository as a "content node" which means the repository needs to know about each type of node it will store to be able to index nodes data. Once it indexes this data, it then query nodes using that data or performs any internal operation over the nodes information.

Then the concept and definition of "Node Type" become extremely important for the query editors as well as one of the most powerful features of the JCR repository. As a consequence, on Jahia xCM, this will be the base technology for a lot of conventional tasks when implementing functionalities for a website. A good documentation for this topic is available on the Apache Jackrabbit website, there you can learn about Node Type Definitions creation, inheritance, constraints, etc.

Let's start with a Node Type Definition for a specific type of content on a Jahia project: Page

Name: jnt:page
Type: nt:nodeType
Properties:
    jcr:hasOrderableChildNodes:  true
    jcr:isMixin:  false
    jcr:nodeTypeName:  jnt:page
    jcr:mixinTypes: []
jcr:supertypes: 
    jmix:basemetadata
    jmix:hasTemplateNode
    jmix:navMenuItem
    jmix:nodenameInfo
    jmix:observable
    jmix:publication
    jmix:tagged
    mix:title
    nt:base

On the Node Type Definition for the Page we can see the list of properties and the list of super types this node inherits properties from. Then if we want to use this node on a query, we can write a sentence like:

select * from [jnt:page] as page order by page.[jcr:lastModified] desc

The result of this query will be a list of content nodes of type jntage and ordered by the jcr:lastmodified (Date) property value.

Note that on this sample query we had used a specific content node (jntage) and one inherited property of this content node (jcr:lastModified). You can try to build the entire inheritance tree for jntage to check all the node properties available for querying. Now you can think about the power of queries when you need to build custom lists of content on your project, like customized navigations for pages or lists of specific components.

One remarkable thing this sample shows to us is the importance of the knowledge about the content Node Type Definition (CND files on Jahia) of the Jahia Core API and the specific project content created for the developers.

I believe this is the most important and useful feature of the entire Jahia xCM.

On a future post I want to go deeper on more elaborated queries (JCR-SQL2 and JCR-JQOM) and the Jahia Admin Tool. A very useful feature of this web application is a JCR browser where you can test your JCR queries.

References:

1 www.wikipedia.org