Reputation: 11
Using the Query Builder (http://localhost:4502/libs/cq/search/content/querydebug.html
), I would want to get a list of pages that do not have a jcr:content
child node.
I tried with node, item name etc., but could not find the correct query. Appreciate your help.
path=/content/products
type=cq:Page
node=jcr:content
node.operation=exists
node.operation=not
p.limit=-1
Upvotes: 1
Views: 7659
Reputation: 9304
CQ5 Query Builder transforms provided query into a Jackrabbit XPath query. The latter doesn't support testing the child existence. Following XPath theoretically should work:
/jcr:root/content//element(*, cq:Page)[not(jcr:content)]
but the result is empty. There is a JIRA improvement to add such feature, but it looks abandoned.
So, we have to check it manually. Because CQ predicates doesn't offer such feature (there is no node
predicate that you used in your query) we need to write a new predicate:
@Component(metatype = false, factory = "com.day.cq.search.eval.PredicateEvaluator/child")
public class ChildrenPredicateEvaluator extends AbstractPredicateEvaluator {
public boolean includes(Predicate p, Row row, EvaluationContext context) {
final Resource resource = context.getResource(row);
final String name = p.get("name", "");
final boolean childExists;
if (name.isEmpty()) {
childExists = resource.hasChildren();
} else {
childExists = resource.getChild(name) != null;
}
final String operator = p.get("operator", "exists");
if ("not_exists".equals(operator)) {
return !childExists;
} else {
return childExists;
}
}
public boolean canXpath(Predicate predicate, EvaluationContext context) {
return false;
}
public boolean canFilter(Predicate predicate, EvaluationContext context) {
return true;
}
}
We can use it as follows:
child.name=wantedChild
child.operator=exists
// or
child.name=unwantedChild
child.operator=not_exists
You may also skip the child.name
line to check if any children exist / don't exist.
So, your query using this predicate would look like this:
path=/content/products
type=cq:Page
child.name=jcr:content
child.operator=not_exists
p.limit=-1
Upvotes: 3