Having a glimpse at the WCM Search API and the Query Builder (AEM)

Search Class The searching capabilities of the com.day.cq.wcm.foundation package are exposed through the Search class. According to the documentation “The …

Search Class

The searching capabilities of the com.day.cq.wcm.foundation package are exposed through the Search class.

According to the documentation “The Search class implements the search logic used in the foundation searching component and exposes the query result in a scripting friendly object structure”(1). The searching instance is created based on a given request.

Lets see an example of its usage:


// Creating the search object
Search search = new Search(request);
// Setting the query string
search.setQuery('/content/mynode OR /content/geometrixx/en/products');
// Getting the result
Search.Result result = search.getResult();
// Iterating through the result hits
List hits = result.getHits();
for (Search.Hit hit : hits) {
// Do something with the hits
}

We can add more flexibility to the query creation if we get it from a query parameter in the requested? URL, that way we can easily change the query when we need it.

Query Builder

The Search class filters out wildcards (?, *) so, if we need to use wildcards our best option is to use the QueryBuilder interface.

When we use the QueryBuilder we express the specific constraints as predicates. This service also allows us to store the queries in the repository and load them again when needed.

Let’s see an example of its usage:


Map map = new HashMap();
map.put("path", "/content");
map.put("type", "cq:PageContent");
map.put("1_property", "jcr:path");
map.put("1_property.operation", "like");
map.put("1_property.value", "%legal/%");
Query query = builder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();

In the example above, we are storing the query predicates as key/value pairs in a map, but there are other ways to do this.

We can get the predicates through a form POST:


Session session = request.getResourceResolver().adaptTo(Session.class);
Query query = queryBuilder.createQuery(PredicateGroup.create(request.getParameterMap()), session);
SearchResult result = query.getResult();

Or using Predicates instead of the Map:


PredicateGroup group = new PredicateGroup();
group.add(new Predicate("mypath", "path").set("path", "/content"));
group.add(new Predicate("mytype", "type").set("type", "nt:file"));
Query query = builder.createQuery(group, session);
SearchResult result = query.getResult();

There is a handy tool in AEM to test your predicates, it is located in http://localhost:4502/libs/cq/search/content/querydebug.html and it can help you refine your search.

This is an example of a query using different properties with different operations:


path=/content
1_property=jcr:primaryType
1_property.operation=unequals
1_property.value=nt:frozenNode
2_property=jcr:primaryType
2_property.operation=equals
2_property.value=cq:PageContent
3_property=jcr:path
3_property.operation=like
3_property.value=%legal/%
4_property=title
4_property.operation=equals
4_property.value=mypage

In the example above, the first property (1_property) checks that the jcr:primaryType is different than nt:frozenNode. The second property (2_property) checks that the jcr:primaryType is equal to cq:PageContent. The third property () checks that the jcr:path resembles the path ‘%legal/%’, where ‘%’ are used as wildcards. The fourth property (4_property) checks that the custom property ‘title’ equals ‘mypage’.

In that example all the properties work as an‘AND’, if we want them to work as an ‘OR’ we should create a group and use the “p” option:


1_group.path=/content
1_group.1_property=jcr:primaryType
1_group.1_property.operation=unequals
1_group.1_property.value=nt:frozenNode
1_group.2_property=jcr:primaryType
1_group.2_property.operation=equals
1_group.2_property.value=cq:PageContent
1_group.3_property=jcr:path
1_group.3_property.operation=like
1_group.3_property.value=%legal/%
1_group.4_property=title
1_group.4_property.operation=equals
1_group.4_property.value=mypage
1_group.p.or=true

References

(1) https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/javadoc/com/day/cq/wcm/foundation/Search.html
(2) https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/javadoc/com/day/cq/search/QueryBuilder.html

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

Keep reading

More >