How do I find all the content that uses a given node type or mixin?
Question
How do I find all the content that uses a given node type or mixin?
Answer
Query for it. A JCR-SQL2 query selecting from the type returns every node of that type:
SELECT * FROM [myt:myType]
You can run this from the Groovy console, from a module, or through GraphQL:
{
jcr(workspace: EDIT) {
nodesByQuery(query: "SELECT * FROM [myt:myType]", queryLanguage: SQL2, limit: 500) {
nodes { path }
}
}
}
It includes subtypes, and that is usually a surprise
Selecting from a type matches every node whose type extends it. Measured on 8.2.3.2:
| Query | Rows |
|---|---|
SELECT * FROM [jnt:bigText] | 9 |
SELECT * FROM [jnt:content] | 252 |
SELECT * FROM [jnt:content] WHERE [jcr:primaryType] = 'jnt:bigText' | 9 |
So a query on a broad supertype answers a much bigger question than you asked. When you want that type and not its descendants, constrain the primary type explicitly:
SELECT * FROM [jnt:content] WHERE [jcr:primaryType] = 'myt:myType'
Mixins work the same way - you do not need to inspect jcr:mixinTypes
This is the part people usually miss and work around badly. Selecting from a mixin finds the nodes that carry it:
| Query | Rows |
|---|---|
SELECT * FROM [jmix:keywords] | 3 |
SELECT * FROM [mix:title] | 502 |
There is no need to search the jcr:mixinTypes property as a string, which is
the usual hand-rolled approach and is both slower and easy to get wrong on
multi-valued data.
Scope it
An unscoped query runs across everything the session can see, including
/modules and system content - which is why mix:title returns 502 above on an
otherwise empty instance.
SELECT * FROM [myt:myType] WHERE ISDESCENDANTNODE('/sites/mySite')
Which workspace you ask matters
A query against EDIT tells you what authors have; against LIVE, what is published. Checking whether a type is still in use before removing it from a definition means asking both - content can exist in LIVE that no longer exists in EDIT, and vice versa.
What this does not tell you
This finds content instances. It does not find references to the type in code - views, JSON form overrides, rules, other CND files that extend it. For those, search the source of your modules.
Both matter before removing a type: content instances will break on load, and a
view that extends a type that no longer exists will fail at render.
This article was drafted with AI assistance, then reviewed and curated by Jahia Customer Support engineers before publication.