3
votes

I want to search the entire content tree but not specific tress that have a 'Do Not Search' property at their base.

The Query Builder API page does not reference anything besides AND and OR.

Is it possible to exclude paths from the search or can I only explicitly include paths?

The first three lines are "/content AND /content/path/es". I want "/content AND NOT(/content/path/es)"

map.put("group.1_path", "/content");
map.put("group.2_path", "/content/path/es");
map.put("group.p.or","false");

I have tried the next two both true and false and they have no effect.

map.put("group.2_path.p.not", "true");
map.put("group.2_path.not", "true");
map.put("group.2_path", "not('/content/path/es')");

I can't find any documentation that mentions any other name that 'not' or '!' might be used instead.

4

4 Answers

3
votes

Yes it is possible. But not exactly in the way you are trying.

You can exclude the pages with certain properties using the property predicate evaluator.

For ex. If you want to exclude pages which have the property "donotsearch" in its jcr:content node, then you can query it using property operation as exists

map.put("path", "/content/geometrixx/en/toolbar");
map.put("type", "cq:Page");
/* Relative path to the property to check for */
map.put("property", "jcr:content/donotsearch"); 
/* Operation to perform on the value of the prop, in this case existence check */
map.put("property.operation", "exists"); 
/* Value for the prop, false = not, by default it is true */
map.put("property.value", "false"); 

This would result in the following XPath Query

/jcr:root/content/geometrixx/en/toolbar//element(*, cq:Page)
[
not(jcr:content/@donotsearch) 
]

But in case you would like to exclude pages with certain value for the property donotsearch, then you can change the above query as shown below

map.put("property", "jcr:content/donotsearch"); //the property to check for
map.put("property.operation", "equals"); // or unequals or like etc..
map.put("property.value", "/*the value of the property*/");

You can find a lot other info regarding querying by referring to the docs.

2
votes

I'm not sure what version of CQ you're using (you linked to the 5.4 docs), but in 5.5 and above, the PredicateGroup class has a setNegated method to exclude results that would match the group defined.

You can't set negation on an individual Predicate, but there would be nothing to stop you creating a group with just the predicate that you wish to negate:

Predicate pathPredicate = new Predicate("path").set("path", "/content/path/es");
PredicateGroup doNotSearchGroup = new PredicateGroup();

doNotSearchGroup.setNegated(true);
doNotSearchGroup.add(pathPredicate);

Query query = queryBuilder.createQuery(doNotSearchGroup);

EDIT: Just to update in relation to your comment, you should be able to add a PredicateGroup to another PredicateGroup (as PredicateGroup is a subclass of Predicate). So once you have your negated group, combine it with the path search:

Predicate pathPredicate = new Predicate("path");
pathPredicate.set("path", "/content");

PredicateGroup combinedPredicate = new PredicateGroup();
combinedPredicate.add(pathPredicate);
combinedPredicate.add(doNotSearchGroup);

Query query - queryBuilder.createQuery(combinedPredicate);
1
votes

It is pretty straightforward implementation. Use

map.put("group.p.not",true)
map.put("group.1_path","/path1/where/you/donot/want/to/search")
map.put("group.2_path","/path2/where/you/donot/want/to/search")
0
votes

I've run into the same problem and while I couldn't fully solve it I was able to come up with a workaround using groups and the unequals operator. Something like:

path=/var/xxx

1_property=jcr:primaryType
1_property.value=rep:ACL
1_property.operation=unequals

2_property=jcr:primaryType
2_property.value=rep:GrantACE
2_property.operation=unequals

Btw, map.put("group.p.not",true) did not work for me.

This link has a lot of useful information: https://hashimkhan.in/2015/12/02/query-builder/