Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

SlingQuery find() vs has() and default strategy

Avatar

Level 1

All,

Trying to confirm my understanding

1. What is the difference between has() and find()

2. If no search strategy is selected what is the default set?
$(resource).has(foundation/components/richtext) vs  $(resource).searchStrategy(SearchStrategy.DFS).has("dam:Asset:first")

3. Using searchstrategy on a large sub tree throws "SlingQuery Number of processed resources exceeded 100. Consider using a JCR query instead of SlingQuery."

 

Thanks

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @Nicole_estee ,

 

1. has() generally used with the selectors that have descendants matching the selectors while find() for each resource in collection return all its descendants using selected strategy. Actually, the find() operation uses QUERY strategy by default, which means that the selector string is transformed to a SQL2 query.

 

2. Sling queries doesn't use indexes and generally in queries traversing large subtrees (like / or /content) it'll be much slower than well written JCR query.

View solution in original post

4 Replies

Avatar

Correct answer by
Community Advisor

Hi @Nicole_estee ,

 

1. has() generally used with the selectors that have descendants matching the selectors while find() for each resource in collection return all its descendants using selected strategy. Actually, the find() operation uses QUERY strategy by default, which means that the selector string is transformed to a SQL2 query.

 

2. Sling queries doesn't use indexes and generally in queries traversing large subtrees (like / or /content) it'll be much slower than well written JCR query.

Avatar

Community Advisor

Hi,
You can find detals at https://sling.apache.org/documentation/bundles/sling-query/methods.html#searchstrategystrategy

1.Actually, the find() operation uses QUERY strategy by default, which means that the selector string is transformed to a SQL2 query. However, the transformation process is very naïve and simply skips all conditions that can't be easily transformed to SQL2 (eg. selector [jcr:content/jcr:title=some title] won't be transformed as it contains some subresource reference). The result of this query is then filtere manually. See searchStrategy for more details.

2.

.searchStrategy(strategy)

Select new search strategy, which will be used in following find() and has() function invocations. There 3 options:

DFS and BFS iterate through descendants using appropriate algorithm. QUERY strategy tries to transform SlingQuery selector into a SQL2 query and invokes it. Because there are SlingQuery operations that can't be translated (eg. :has() modifier), the SQL2 query result is treated as a initial collection that needs further processing.

3. Sling Query is not meant to replace JCR queries (XPath, JCR-SQL, JCR-SQL2). It doesn't use indexes and generally in queries traversing large subtrees (like / or /content or /content/mysite/en) it'll be much slower than well written JCR query.



Arun Patidar

Avatar

Level 1

Thanks @arunpatidar @TarunKumar  i concur with responses,.. There are portions that i am unclear, hence trying to put it in a different way,

 

1. My requirement was to find if any of the descendant folder for a parent, has an asset to in turn display the parent folder. It is nested. I used $(resource).searchStrategy(SearchStrategy.DFS).has("dam:Asset:first") or $(resource).searchStrategy(SearchStrategy.DFS).find("dam:Asset:first")  the error with traversal was found. That means with ".searchStrategy(SearchStrategy.DFS)" the below error is thrown


"SlingQuery Number of processed resources exceeded 100. Consider using a JCR query instead of SlingQuery.
"

 

I knocked off the bolded section, for "has" or "find",  $(resource).has("dam:Asset:first") or $(resource).find("dam:Asset:first") and although it retrieved the result, the error was no longer visible and hence the below questions.

 

2.  if i do not include "searchStrategy(SearchStrategy.DFS)", for "has" or "find",  it uses Query strategy by default based on details above  . Does this use index?

eg: $(resource).has(foundation/components/richtext) instead of  $(resource).searchStrategy(SearchStrategy.DFS).has("dam:Asset:first")

 

3. Wrt differences what i am trying to gauge is, in terms of functionality which one is quicker ? I would imagine "has".. IMO,  "find" retrieve the entire list of resources matching selector for later iteration while "has" just checks if any descendants of that parent  contains the selector and returns the parent node for which you check if descendants contain a selector 

Regards,

Avatar

Community Advisor

Hi,

As per my understanding the Sling query does not uses the index and much slower as compared to JCR queries.

 

Has method

Pick such resources from the collection that have descendant matching the selector.

 

Find method vs JCR

  • find() is powerful but may be dangerous
  • it should be used only for small subtrees becaus it collect whole tree and apply selector
  • if you want to query a large space, use JCR-SQL[2] or XPath
  • if your SlingQuery processes more than 100 resources, you’ll get a warning in the logs:
24.02.2020 13:35:49.942 *WARN* [0:0:0:0:0:0:0:1 [1401276949857] POST /bin/groovy
console/post.json HTTP/1.1] SlingQuery Number of processed resources exceeded 10
0. Consider using a JCR query instead of SlingQuery.


Arun Patidar