Expand my Community achievements bar.

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

Query builder api vs JCR search API

Avatar

Level 7

Is there any advantages of using Querybuilder  API instead of JCR search api?

And as we know that QueryManager wll come into picture in case of JCR search api just to create query and here Querybuilder is use to create query ...is there any extra benfit using Query Builder API instead of QueryManager ?

I have checked all possible links available by searching these keywords but exact difference and benefitsI did not get .

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Hi,

Query builder is built on top of JCR Query API. When we use query builder, we deal with a map of predicates instead of queries. The Out of the box predicates work in most situations. The limit and offset features work like a charm for pagination situations. Grouping let's you write complex queries in a very readable manner. One more nice feature is the faceted search, your search results can be split by tags. Query builder returns resources and not the nodes, so you don't have to handle to deal with the checked repository exceptions that come along with JCR API ( https://cqdump.wordpress.com/2012/11/06/cq5-coding-patterns-sling-vs-jcr-part-1/ ).

Since it is exposed as a REST servlet, it is often used in building interfaces like custom dashboards and the familiarity helps.

For more details, please refer following articles:

cq5 - CQ QueryBuilder API.. why? - Stack Overflow

http://aempodcast.com/2015/aem-resources/aem-queries-xpath-jcr-sql2-query-builder-syntaxes/#.W9MjTWg...

Exact difference between Jcr-xql2, xpath query and query builder api

I hope this information helps!

Regards,

Lavanya Malyala

View solution in original post

4 Replies

Avatar

Correct answer by
Former Community Member

Hi,

Query builder is built on top of JCR Query API. When we use query builder, we deal with a map of predicates instead of queries. The Out of the box predicates work in most situations. The limit and offset features work like a charm for pagination situations. Grouping let's you write complex queries in a very readable manner. One more nice feature is the faceted search, your search results can be split by tags. Query builder returns resources and not the nodes, so you don't have to handle to deal with the checked repository exceptions that come along with JCR API ( https://cqdump.wordpress.com/2012/11/06/cq5-coding-patterns-sling-vs-jcr-part-1/ ).

Since it is exposed as a REST servlet, it is often used in building interfaces like custom dashboards and the familiarity helps.

For more details, please refer following articles:

cq5 - CQ QueryBuilder API.. why? - Stack Overflow

http://aempodcast.com/2015/aem-resources/aem-queries-xpath-jcr-sql2-query-builder-syntaxes/#.W9MjTWg...

Exact difference between Jcr-xql2, xpath query and query builder api

I hope this information helps!

Regards,

Lavanya Malyala

Avatar

Level 7

Hi Lavanya ..Thanks ...very Helpful

some doubts if you can clear this also it would be very helpful.

  • The limit and offset features work like a charm for pagination situations: 

in JCR api as well we can get this

Query query = queryManager.createQuery(queryString, Query.SQL);
QueryImpl q = (QueryImpl) query;
q
.setLimit(10);
q
.setOffset(10);

we can set this ....?? 

Avatar

Community Advisor

More info about Query Builder Api you can find below:

Query Builder API

Example Query Builder API Usage

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

   String fulltextSearchTerm = "Geometrixx";

                 

    // create query description as hash map (simplest way, same as form post)

    Map<String, String> map = new HashMap<String, String>();

 

// create query description as hash map (simplest way, same as form post)

    map.put("path", "/content");

    map.put("type", "cq:Page");

    map.put("group.p.or", "true"); // combine this group with OR

    map.put("group.1_fulltext", fulltextSearchTerm);

    map.put("group.1_fulltext.relPath", "jcr:content");

    map.put("group.2_fulltext", fulltextSearchTerm);

    map.put("group.2_fulltext.relPath", "jcr:content/@cq:tags");

    // can be done in map or with Query methods

    map.put("p.offset", "0"); // same as query.setStart(0) below

    map.put("p.limit", "20"); // same as query.setHitsPerPage(20) below

                   

    Query query = builder.createQuery(PredicateGroup.create(map), session);

    query.setStart(0);

    query.setHitsPerPage(20);

             

    SearchResult result = query.getResult();

    // paging metadata

    int hitsPerPage = result.getHits().size(); // 20 (set above) or lower

    long totalMatches = result.getTotalMatches();

    long offset = result.getStartIndex();

    long numberOfPages = totalMatches / 20;

                

    //Place the results in XML to return to client

    DocumentBuilderFactory factory =     DocumentBuilderFactory.newInstance();

    DocumentBuilder builder = factory.newDocumentBuilder();

    Document doc = builder.newDocument();

                             

    //Start building the XML to pass back to the AEM client

    Element root = doc.createElement( "results" );

    doc.appendChild( root );

                

    // iterating over the results

    for (Hit hit : result.getHits()) {

       String path = hit.getPath();

      //Create a result element

      Element resultel = doc.createElement( "result" );

      root.appendChild( resultel );

                    

      Element pathel = doc.createElement( "path" );

      pathel.appendChild( doc.createTextNode(path ) );

      resultel.appendChild( pathel );

    }



Arun Patidar
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] ----