The Query Builder is a great tool that allows us to search for nodes in the JCR. We often as AEM developers use this tool to build a query for us to use in the backend to build query descriptions (predicates); the set of predicates produced will call the Predicate Evaluator which knows how to handle that specific predicate for XPath, filtering, and facet extraction.
In this article, we will be sharing query examples to find all AEM pages with specific page page properties using the Query Builder Debugger tool.
1. Find all AEM pages with a single page property
Find all pages under /content/we-retail,
and has page properties set with cq:productMaster == ‘/var/commerce/products/we-retail/wo/pants/faba_running_pants’
show max results.
1 2 3 4 5 6 | path=/content/we-retail type=cq:Page property=jcr:content/cq:productMaster property.value= /var/commerce/products/we-retail/wo/pants/faba_running_pants p.limit=-1 |
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.day.cq.search.QueryBuilder; import com.day.cq.search.result.SearchResult; import com.day.cq.search.result.Hit; import com.day.cq.search.Query; import org.json.JSONArray; import org.json.JSONObject; import javax.servlet.Servlet; import java.io.IOException; import java.util.Collections; import java.util.Map; @Component( service = Servlet.class, property = { "sling.servlet.paths=/bin/queryservlet", "sling.servlet.methods=GET" } ) public class QueryServlet extends SlingAllMethodsServlet { @Reference private ResourceResolverFactory resolverFactory; @Reference private QueryBuilder queryBuilder; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); final Map<String, Object> authInfo = Collections.singletonMap( ResourceResolverFactory.SUBSERVICE, "sourcedCodeSystemUser"); try (ResourceResolver resourceResolver = resolverFactory.getServiceResourceResolver(authInfo)) { String queryPath = "/content/we-retail"; String queryType = "cq:Page"; String queryProperty = "jcr:content/cq:productMaster"; String queryPropertyValue = "/var/commerce/products/we-retail/wo/pants/faba_running_pants"; Map<String, String> queryParams = new HashMap<>(); queryParams.put("path", queryPath); queryParams.put("type", queryType); queryParams.put("property", queryProperty); queryParams.put("property.value", queryPropertyValue); Query query = queryBuilder.createQuery(PredicateGroup.create(queryParams), resourceResolver.adaptTo(javax.jcr.Session.class)); SearchResult result = query.getResult(); JSONArray resultsArray = new JSONArray(); for (Hit hit : result.getHits()) { Resource resource = hit.getResource(); JSONObject pageData = new JSONObject(); pageData.put("path", resource.getPath()); resultsArray.put(pageData); } JSONObject jsonResponse = new JSONObject(); jsonResponse.put("results", resultsArray); response.getWriter().write(jsonResponse.toString()); } catch (Exception e) { JSONObject errorResponse = new JSONObject(); errorResponse.put("error", "An error occurred while processing the request."); response.getWriter().write(errorResponse.toString()); } } } |
Curl Example
1 | curl -X GET http://localhost:4502/bin/queryservlet |
Output
1 2 3 4 5 6 7 8 9 10 11 | { "results": [ { "path": "/content/we-retail/en" }, { "path": "/content/we-retail/de" } // ... more paths ] } |
2. Find all AEM pages with multiple page properties
Find all pages under /content/we-retail,
and has page properties set with cq:productMaster == ‘/var/commerce/products/we-retail/wo/pants/faba_running_pants’
and has page properties set with cq:template == ‘/conf/we-retail/settings/wcm/templates/product-page’
show max results.
1 2 3 4 5 6 7 8 9 10 11 | path=/content/we-retail type=cq:Page path=/content/we-retail type=cq:Page group.1_property=jcr:content/cq:productMaster group.1_property.value= /var/commerce/products/we-retail/wo/pants/faba_running_pants group.2_property=jcr:content/cq:template group.2_property.value= /conf/we-retail/settings/wcm/templates/product-page p.limit=-1 |
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.day.cq.search.QueryBuilder; import com.day.cq.search.result.SearchResult; import com.day.cq.search.result.Hit; import com.day.cq.search.Query; import org.json.JSONArray; import org.json.JSONObject; import javax.servlet.Servlet; import java.io.IOException; import java.util.Collections; import java.util.Map; @Component( service = Servlet.class, property = { "sling.servlet.paths=/bin/queryservlet", "sling.servlet.methods=GET" } ) public class QueryServlet extends SlingAllMethodsServlet { @Reference private ResourceResolverFactory resolverFactory; @Reference private QueryBuilder queryBuilder; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); final Map<String, Object> authInfo = Collections.singletonMap( ResourceResolverFactory.SUBSERVICE, "sourcedCodeSystemUser"); try (ResourceResolver resourceResolver = resolverFactory.getServiceResourceResolver(authInfo)) { Map<String, String> queryParams = new HashMap<>(); queryParams.put("path", "/content/we-retail"); queryParams.put("type", "cq:Page"); queryParams.put("group.1_property", "jcr:content/cq:productMaster"); queryParams.put("group.1_property.value", "/var/commerce/products/we-retail/wo/pants/faba_running_pants"); queryParams.put("group.2_property", "jcr:content/cq:template"); queryParams.put("group.2_property.value", "/conf/we-retail/settings/wcm/templates/product-page"); queryParams.put("p.limit", "-1"); Query query = queryBuilder.createQuery(PredicateGroup.create(queryParams), resourceResolver.adaptTo(javax.jcr.Session.class)); SearchResult result = query.getResult(); JSONArray resultsArray = new JSONArray(); for (Hit hit : result.getHits()) { Resource resource = hit.getResource(); JSONObject pageData = new JSONObject(); pageData.put("path", resource.getPath()); resultsArray.put(pageData); } JSONObject jsonResponse = new JSONObject(); jsonResponse.put("results", resultsArray); response.getWriter().write(jsonResponse.toString()); } catch (Exception e) { JSONObject errorResponse = new JSONObject(); errorResponse.put("error", "An error occurred while processing the request."); response.getWriter().write(errorResponse.toString()); } } } |
Find all AEM Pages with Tags with Query Builder API
Your code does not compile because is missing
import com.day.cq.search.Query;
Thanks for catching that, this is fixed now.
This is the best! thanks.