Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

QueryBuilder or fetching the pages and then Iterating

Avatar

Former Community Member

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
Former Community Member

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

4 Replies

Avatar

Former Community Member

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

Former Community Member

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

Former Community Member

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

Avatar

Correct answer by
Former Community Member

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

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----