Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

SOLVED

QueryBuilder or fetching the pages and then Iterating

Avatar

Level 3

Hi,

I have a requirement wherein I need to search for article pages of a specific type under 6 different paths. The pages belonging to 6 different paths are of same type in a way that they are using same template. Their respective parent pages are also using the same template but they differ based on specific custom page property that we are setting. The detailed pages are further characterized by custom page properties. So based on these custom page properties and latest replication date I have to select one article each(making it a total 6 article pages) among all the article pages that belong to 6 different paths. What is the best way possible ? Using QueryBuilder API or fetching the pages using the listChildren method and then tweaking the list to remove the unwanted selections. Also, could you please explain the reason as well.

Edit: Is it possible to restrict the number of results returned by QueryBuilder API.

Thanks in advance,

Ankit Chandrawat

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hello Ankit,

         map.put("path", "/content/");
        map.put("type", "cq:Page");
        map.put("property", "jcr:content/<<private_or public property>>");
        map.put("property.value", "public");        
       map.put("orderby", "@jcr:content/jcr:lastReplicated");

The above should work.

Thanks,

Anwar

View solution in original post

0 Replies

Avatar

Level 2

Query Builder is the way to go about this considering the complexity of your use case

Create an Util class (Say SearchUtil.java) and place the below static method in it:

public static Iterator<Node> searchForPages(Session session, QueryBuilder builder) {
        if (builder == null) {
            throw new RuntimeException("No queryBuilder service attached to SearchQuery"
                   );
        } else {
            log.info("Way to go...");
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("path", "/content/");
        map.put("type", "cq:Page");
        map.put("property", "jcr:content/<<[CUSTOM_PROPERTY1_NAME]>>");
        map.put("property.value", "<<[CUSTOM PROPERTY1 VALUE]>>");
        map.put("property", "jcr:content/<<[CUSTOM_PROPERTY2_NAME]>>");
        map.put("property.value", "<<[CUSTOM PROPERTY2 VALUE]>>");
        map.put("property", "jcr:content/<<[CUSTOM_PROPERTY3_NAME]>>");
        map.put("property.value", "<<[CUSTOM PROPERTY3 VALUE]>>");
       map.put("orderby", "@jcr:content/cq:lastModified");

        PredicateGroup group = PredicateConverter.createPredicates(map);
        Query query = builder.createQuery(group, session);
        query.setHitsPerPage(0);
        SearchResult result = query.getResult();
        Iterator<Node> nodeIter = result.getNodes();
                
        log.info("Finished : asc");
        return nodeIter;
    }

And to your question on restricting the # of results:

query.setHitsPerPage(0); --> will return all the matching nodes

query.setHitsPerPage(<<number of hits>>); --> Will return the first 'n' hits based on the sorting (governed by orderby used in the map) you have chosen (in the above code it display all the results sorted by 'cq:lastModified' property)

Avatar

Level 3

Hi Anwar,

Thank you for your response. I would also like to let you know that it is possible that the author may not select that custom page property on article page. So, the logic has to be something like check for all the pages that have the custom page property selected by author and then sort it as per replicated date and then return the one with the latest replicated date. In case the user has not selected the custom page property on any of the pages we need to return the page with latest replication date. Adding to it there is another custom page property public/private. So we need to remove all those pages that are selected as private. Do you think this can be handled using QueryBuilder as well.

Thanks,

Ankit

Avatar

Level 3

Thanks for the reply Anwar. Looks like this should help.

Avatar

Correct answer by
Level 2

Hello Ankit,

         map.put("path", "/content/");
        map.put("type", "cq:Page");
        map.put("property", "jcr:content/<<private_or public property>>");
        map.put("property.value", "public");        
       map.put("orderby", "@jcr:content/jcr:lastReplicated");

The above should work.

Thanks,

Anwar