QueryBuilder snippets
Purpose: The query recipes that cover most listing/search features, with the safety rails included.
Who this page is for
| Audience | Why it matters to you |
|---|---|
| Backend engineers | Query authors |
Java invocation skeleton
@Reference private QueryBuilder queryBuilder;
Map<String, String> params = Map.of(
"type", "cq:Page",
"path", "/content/phi/plans",
"1_property", "jcr:content/isGoldTier",
"1_property.value", "true",
"orderby", "@jcr:content/jcr:title",
"p.limit", "20"); // ALWAYS bounded
Session session = resolver.adaptTo(Session.class);
SearchResult result = queryBuilder.createQuery(PredicateGroup.create(params), session).getResult();
for (Hit hit : result.getHits()) {
Page page = hit.getResource().adaptTo(Page.class); // resolve via the resolver's ACLs
}
Recipe box (paste into querydebug.html to try)
Pages by template:
type=cq:Page
path=/content/phi
property=jcr:content/cq:template
property.value=/conf/phi-academy/settings/wcm/templates/plan-page
p.limit=50
Pages tagged (incl. descendant tags):
type=cq:Page
path=/content/phi
tagid=phi:plans/hospital
tagid.property=jcr:content/cq:tags
p.limit=50
Assets modified in the last week:
type=dam:Asset
path=/content/dam/phi
relativedaterange.property=jcr:content/jcr:lastModified
relativedaterange.lowerBound=-7d
p.limit=100
Full-text with facet-ready grouping:
fulltext=hospital excess
path=/content/phi
type=cq:Page
group.1_group.property=jcr:content/tier
group.1_group.property.value=gold
group.p.or=true
p.limit=20
p.offset=0 ← pagination pair
Safety rails (repeat until habitual)
Bounded limit always; path+type always; verify the plan with Explain before shipping (queries); user input into predicate values only — never concatenated into keys or raw JCR-SQL2 (injection).