Made by DhawalMade by Dhawal
AEMRuns in your browser

AEM Query Builder

Build QueryBuilder predicates visually and get the JSON URL, Java and JCR-SQL2 versions.

Updated 31 October 2026How to use it ↓

Where to search

Only nodes under this path are searched.

Property conditions

All conditions must match. For “either of”, use an OR group below.

Dates
Tags

One per line, e.g. mysite:topics/aem.

Full-text, similarity, date comparison and OR groups
Full-text search
Similar to (rep:similar)

Ranks nodes whose text and metadata resemble one node. It does not compare how images look.

Compare two dates

For example, pages edited after they were last published. This filters results one by one, so keep the path narrow.

Sorting and results

Use -1 for all results.

User guide

What this tool does

The AEM Query Builder lets you build a QueryBuilder query in a form instead of typing predicates by hand. As you fill it in, it writes the same query four ways: predicate text for the Query Debugger, a /bin/querybuilder.json URL, Java code using the QueryBuilder API, and an approximate JCR-SQL2 version. It also checks the query for common mistakes and slow patterns.

It works for both AEM as a Cloud Service and AEM 6.5. The version switch changes the index and debugging advice.

When to use it

  • Finding content during development or support: every page using a component, every asset of one type, fragments of one model.
  • Writing a query for code: get the predicates right in the form, then copy the Java version into a Sling Model or servlet.
  • Debugging a slow or empty query: paste an existing query from your logs or code and read the checks.
  • Content audits: pages not modified in a year, pages missing a tag, pages with a given template.
  • Moving a query between forms: turn a querybuilder.json URL from a colleague into Java, or into JCR-SQL2 for a custom index test.

How to use it

  1. Pick your AEM version at the top: AEM as a Cloud Service or AEM 6.5.
  2. Start from a preset if one is close to what you need, or fill in the form from scratch.
  3. Set where to search. Always give a path and a node type: they decide which index Oak can use. Use cq:Page for pages, dam:Asset for assets and fragments, and nt:unstructured for component nodes.
  4. Add property conditions. Each one needs a property path relative to the node type, a condition and one or more values. Several values match any of them unless you tick All values must match. All the conditions in this section must match together.
  5. Add dates, tags or full-text if you need them. Relative dates such as -7d move with the clock; fixed dates do not.
  6. Use an OR group when you need “either this or that”: at least one condition inside the group must match.
  7. Set sorting and results. QueryBuilder returns only 10 results unless you set p.limit. Use -1 for all results, together with p.guessTotal.
  8. Copy the output you need from the tabs on the right, and read the Checks tab.
  9. Run it against your AEM. Enter your author URL once, for example http://localhost:4502, then use Open in Query Debugger or Run as JSON. The links open in a new tab and use the AEM login you already have in that browser.

Presets

The Start from a preset menu fills in a complete query you can adjust. After loading, a note above the form says what to change, usually the site path or an example value.

Preset Finds
Page finder Pages whose title contains a word (case-sensitive)
Pages modified in the last 7 days Recently edited pages, newest first
Template usage Every page built from one editable template
Unpublished pages Pages never published, or whose last action was Unpublish
Stale pages: edited since last publish Published pages with edits that are not live yet, using dateComparison
Stale pages: not updated in 12 months Old content that may need a review or removal
Missing SEO metadata Pages without a meta description (jcr:description)
Pages with a tag Pages carrying either of two tags
Where a component is used Every node using a component’s resource type
Full-text search in pages Pages whose content mentions a word
Assets by MIME type Images or documents of given types
Assets missing metadata Assets without a title or description
Duplicate assets Assets with the same file, matched on dam:sha1
Similar assets Assets whose text and metadata resemble one asset, using similar
Content fragments of one model All fragments built from a given model

To work on an existing query, press Import query and paste predicate lines, a /bin/querybuilder.json URL or a Query Debugger URL.

Reading the results

Output What it is Where to use it
Predicates key=value lines, the native QueryBuilder format Paste into the Query Debugger at /libs/cq/search/content/querydebug.html
JSON URL The same query as a GET request Open in a browser where you are logged in to AEM, or call from scripts
Java A Map of predicates passed to QueryBuilder.createQuery OSGi services, Sling Models and servlets
JCR-SQL2 An approximate translation Explain Query, CRXDE’s query tool, QueryManager in code

The checks come in three levels:

  • Problems (✕) are mistakes that will give wrong or no results, such as querying cq:template on a cq:Page instead of jcr:content/cq:template.
  • Warnings (!) are likely performance issues, such as no path, no node type, or fetching every result without p.guessTotal.
  • Notes (i) are advice, such as making sure a sorted property is indexed with ordered=true.

The JCR-SQL2 tab is a translation, not an exact copy. QueryBuilder has evaluators that SQL2 lacks, and relative dates become fixed dates at the moment the query is generated. Always confirm with Explain Query on your instance.

Worked example

You want the 20 most recently changed pages under /content/mysite from the last week. Choose the preset Pages modified in the last 7 days. The predicates are:

path=/content/mysite
type=cq:Page
relativedaterange.property=jcr:content/cq:lastModified
relativedaterange.lowerBound=-7d
orderby=@jcr:content/cq:lastModified
orderby.sort=desc
p.limit=20

On a local author, the JSON URL becomes:

http://localhost:4502/bin/querybuilder.json?path=/content/mysite&type=cq:Page&relativedaterange.property=jcr:content/cq:lastModified&relativedaterange.lowerBound=-7d&orderby=@jcr:content/cq:lastModified&orderby.sort=desc&p.limit=20

And the JCR-SQL2 translation, generated on 1 November 2026:

SELECT s.* FROM [cq:Page] AS s
WHERE ISDESCENDANTNODE(s, '/content/mysite')
  AND s.[jcr:content/cq:lastModified] >= CAST('2026-10-25T00:00:00.000Z' AS DATE)
ORDER BY s.[jcr:content/cq:lastModified] DESC

Notice that the date sits on jcr:content, not on the page node itself. That is the most common reason page queries come back empty.

Limits and privacy

  • Everything runs in your browser. The tool never contacts your AEM; the Open links simply open a new tab, and your browser sends the request with your own login.
  • Your query and author URL are saved in this browser (local storage), so a refresh keeps them. Nothing is sent to this site.
  • Share links contain the query itself. Do not share links that reveal internal paths you would rather keep private.
  • Supported predicates: path, type, nodename, property (all operations), daterange, relativedaterange, dateComparison, similar, tagid, fulltext, OR groups, orderby and the p. options. Other predicates, such as language or hasPermission, are listed as left out when you import a query.
  • Two predicates work differently from the rest. dateComparison cannot use an index: it checks each result after the query runs, so keep its path narrow. similar ranks results by text and metadata through the full-text index, not by how images look.
  • Duplicates are found one file at a time. QueryBuilder cannot group results, so the duplicate preset finds every copy of one file you choose by its dam:sha1. To stop new duplicates, turn on AEM Assets’ duplicate detection at upload; for a whole-DAM report, use a script.
  • Block QueryBuilder on publish. /bin/querybuilder.json should be denied by your Dispatcher filters on publish instances. Use it on author, or behind authentication.

Further reading

FAQ

Does this tool connect to my AEM instance?
No. It builds the query in your browser. The “Open” links open a new tab on your own AEM author, using the login you already have there.
Why does my page query return nothing?
Most often the property is on the wrong node. Page properties such as cq:template, cq:tags and cq:lastModified live on jcr:content, so use jcr:content/cq:template, not cq:template. The Checks tab flags this.
Why do I only get 10 results?
QueryBuilder returns 10 hits unless you set p.limit. Use p.limit=-1 for all results, with p.guessTotal=true so AEM does not count every match first.
Is the JCR-SQL2 output exactly the same query?
It is a close translation for the predicates this tool supports. QueryBuilder adds its own evaluators, so confirm the plan with Explain Query on your instance.
Does it work with AEM as a Cloud Service and AEM 6.5?
Yes. The QueryBuilder API is the same on both. The version switch changes the advice about indexes and where to find Explain Query.