SlingQuery find() vs has() and default strategy | Community
Skip to main content
October 13, 2021
Solved

SlingQuery find() vs has() and default strategy

  • October 13, 2021
  • 2 replies
  • 1527 views

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

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by TarunKumar

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.

2 replies

TarunKumar
Community Advisor
TarunKumarCommunity AdvisorAccepted solution
Community Advisor
October 14, 2021

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.

arunpatidar
Community Advisor
Community Advisor
October 15, 2021

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
October 15, 2021

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,

arunpatidar
Community Advisor
Community Advisor
October 18, 2021

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