Adobe Experience Manager

A quick look into the JCR Search API (AEM)

The JCR Search API allows us to query data located in the AEM Java Content Repository (JCR) using a SQL like grammar.

To be able to use the JCR Search API, first we need to get access to the Session instance. Thus we can get the QueryManager from it. The QueryManager allows us to create Query objects, store queries as Nodes in the repository and reconstructing queries that were stored as Nodes.

So, to create a new Query we would need something like this:

String queryStr = “SELECT * FROM [nt:base] As s WHERE CONTAINS(s.title, 'test')”;
javax.jcr.query.QueryManager queryManager= session.getWorkspace().getQueryManager();
javax.jcr.query.Query query = queryManager.createQuery(queryStr, javax.jcr.query.Query.JCR_SQL2);

In the first line we define the query string. Then we get the QueryManager from the session. Finally, we use the QueryManager to create a new Query specifying the query string and the query language which is JCR SQL2 in this case.

We can run queries against a specific type, like page nodes:

SELECT * FROM [cq:Page]

We can do full text search queries:

SELECT * FROM [nt:unstructured] WHERE CONTAINS('city', 'Colima')
SELECT * FROM [nt:unstructured] AS r WHERE CONTAINS(, 'Colima')

Find nodes under a specific path:

SELECT * FROM [nt:base] AS r WHERE ISDESCENDANTNODE(r, '/content')
SELECT * FROM [nt:base] WHERE jcr:path LIKE '/content/%'

Find nodes by name:

SELECT * FROM [nt:base] WHERE NAME() = 'profile'

Find a page depending on a direct child’s property:

SELECT parent.* FROM [cq:Page] AS parent INNER JOIN [nt:base] AS child ON ISCHILDNODE(child,parent) WHERE ISDESCENDANTNODE(parent, '/content') AND CONTAINS(child.customattribute, 'test')

SELECT parent.* FROM [cq:Page] AS parent INNER JOIN [nt:base] AS child ON ISCHILDNODE(child,parent) WHERE ISDESCENDANTNODE(parent, '/content') AND child.[sling:resourceType] = 'apps/project/page/pagecomponent'

A nice tool for testing queries can be found inside the CRX console. Select the ‘tools’ button and the the ‘query’ option. There you can test XPATH, SQL and SQL2 queries.

Now that we know how to create queries, we can get the results and iterate through them as nodes:

javax.jcr.NodeIterator nodes = results.getNodes();
while (nodes.hasNext()) {
javax.jcr.Node node = nodes.nextNode();
// Do something with the nodes

Or you can get the result rows:

javax.jcr.query.RowIterator rowIterator = result.getRows();
while (rowIterator.hasNext()) {
javax.jcr.query.Row row = rowIterator.nextRow();
javax.jcr.Value[] values = row.getValues();
for(javax.jcr.Value value: values) {
// Do something with the values

For more information about how to get the results please read the documentation of the QueryResult interface.

I hope you find this information useful,If you need more information, please contact us here!
Thanks for reading!

Fixing Rspec and Cucumber random failures in your Continuous Integration Service
Adobe Experience Manager
Having a glimpse at the WCM Search API and the Query Builder (AEM)
Best Practices
De Código, Café Y Cervezas 03 – ReactJS + AngularJS