Author: tomekr
Date: Mon Sep 25 10:28:26 2017
New Revision: 1809599

URL: http://svn.apache.org/viewvc?rev=1809599&view=rev
Log:
SLING-6676: Get more documentation for Sling Query

Added:
    sling/site/trunk/content/documentation/bundles/sling-query/
    
sling/site/trunk/content/documentation/bundles/sling-query/basic-ideas.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/examples.mdtext
    
sling/site/trunk/content/documentation/bundles/sling-query/hierarchy-operators.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/methods.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/modifiers.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/operators.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/selectors.mdtext
    sling/site/trunk/content/documentation/bundles/sling-query/vs-jcr.mdtext

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/basic-ideas.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/basic-ideas.mdtext?rev=1809599&view=auto
==============================================================================
--- 
sling/site/trunk/content/documentation/bundles/sling-query/basic-ideas.mdtext 
(added)
+++ 
sling/site/trunk/content/documentation/bundles/sling-query/basic-ideas.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,75 @@
+Title: Basic ideas
+
+### Collections
+
+`SlingQuery` class represents a collection of resources. Basic collection can 
be created explicitly via a dollar method:
+
+    $(resource1, resource2, resource3)
+    
+Above method creates a new `SlingQuery` object that consists of 3 resources. 
This object implements `Iterable<Resource>` interface, so can be used in 
foreach statements directly:
+
+    for (Resource resource in $(...)) { }
+    
+### Operations
+
+`SlingQuery` class defines a number of methods which can be used to transform 
current collection into a new one. Following code:
+
+    $(resource1, resource2).parent()
+
+will replace each resource with its direct parent. If some resource is a 
repository root, it will be skipped. Some methods replace each resource with 
another resource (eg. `parent()` or `closest()`). Other methods can replace 
each resource with a set of resources:
+
+    $(resource1, resource2).children();
+    
+Resulting object will contain direct children of both `resource1` and 
`resource2` objects. There are also methods that doesn't add any new resources, 
but removes existing:
+
+    $(resource1, resource2).first();
+    
+Methods can be chained to create more complex query. Eg. following code will 
return last direct child of the `resource`:
+
+    $(resource).children().last();
+    
+#### Laziness
+
+All operations are lazy (except `prev()` and sometimes `not()`). It means that 
`SlingQuery` won't read any resources until it's actually necessary. Example:
+
+    $(resource).children().children().first();
+
+`children().children()` construction reads all grand-children of the given 
resource. However, the last method limits the output to the first found 
resource. As a result, `SlingQuery` won't iterate over all children and 
grand-children, but it will simply take the first child of the `resource` and 
return its first child.
+
+#### Immutability
+
+`SlingQuery` object is immutable and each operation creates a new one. We can 
"freeze" some collection before performing more operations on it:
+
+    SlingQuery children = $(resource).children();
+    SlingQuery firstChild = children.first();
+    for (Resource child : children) { /* will display all children */ }
+    for (Resource child : firstChild) { /* will display the first child */ }
+
+### Selectors
+
+Some operations may take an additional string selector parameter that defines 
a filtering. Selector could be used to define resource type, resource 
attributes and additional modifiers. Example selector could look like this:
+
+    "cq:Page"
+    
+It will match all resources with the given resource type. Example:
+
+    $(resource).children("cq:Page")
+    
+will return only children with `cq:Page` resource type. You could also filter 
these resources defining any number of attributes in the square brackets:
+
+    $(resource).children("cq:Page[jcr:title=Some title][jcr:description=Some 
desc]")
+
+And finally, you could add some modifiers at the end:
+
+    $(resource).children("cq:Page[jcr:content/cq:template=my/template]:even")
+
+Above resources will find `cq:Page` children of the resource, using template 
`my/template` and return not all of them, but only those with even indices (eg. 
if matching children of the `resource` are `page_0`, `page_1` and `page_2`, 
only the first and the last will be returned).
+
+All parts of the selector are optional. In fact, an empty string (`""`) is a 
valid selector, accepting all resources. However, the defined order (resource 
type, attributes in square brackets and modifiers) has to be followed. Example 
selectors:
+
+    "foundation/components/richtext" // resource type
+    "foundation/components/richtext:first" // resource type with modifier
+    "[property=value][property2=value2]" // two attributes
+    ":even" // modifier
+    ":even:not(:first)" // two modifiers, the second one is nested
+

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/examples.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/examples.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/examples.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/examples.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,59 @@
+Title: Examples
+
+Get containing page (like 
[PageManager#getContainingPage](http://dev.day.com/docs/en/cq/current/javadoc/com/day/cq/wcm/api/PageManager.html))
+
+    $(resource).closest("cq:Page")
+
+Get first ancestor with a given template
+
+    
$(resource).closest("cq:Page[jcr:content/cq:template=/apps/geometrixx/templates/homepage]")
+
+List siblings of the current page which can be displayed in the navigation
+
+    
$(resource).closest("cq:Page").siblings("cq:Page[jcr:content/hiddenInNav=false]")
+
+Get the first sibling of the current page
+
+    $(resource).closest("cq:Page").siblings("cq:Page").first()
+
+Get page ancestor closest to the root
+
+    $(resource).parents("cq:Page").last()
+
+Get the second child of each resource:
+
+    $(resource1, resource2, resource3).children(":eq(1)")
+
+Get the first two children of each resource:
+
+    $(resource1, resource2, resource3).children(":lt(2)")
+
+Closest ancestor page having non-empty parsys
+
+    $(resource).closest("cq:Page foundation/components/parsys:parent")
+
+Get all parents of the current resource and adapt them to Page object
+
+    Iterable<Page> breadcrumbs = 
$(resource).parents("cq:Page").map(Page.class);
+
+Get all parents of the current resource up to the home page
+
+    Iterable<Page> breadcrumbs;
+    breadcrumbs = $(resource).parentsUntil(
+        "cq:Page[jcr:content/cq:template=/apps/geometrixx/templates/homepage]",
+        "cq:Page").map(Page.class);
+
+List all grand-children pages having empty parsys
+
+    
$(resource).children("cq:Page").children("cq:Page").has("foundation/components/parsys:empty)
+
+Use JCR query to find all `cq:Page`s with a given template
+
+    $(resourceResolver)
+        .searchStrategy(SearchStrategy.QUERY)
+        
.find("cq:PageContent[cq:template=/apps/geometrixx/templates/homepage]")
+        .parent()
+
+Find children named `en` or `de`
+
+    $(resource).children("#en, #de")

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/hierarchy-operators.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/hierarchy-operators.mdtext?rev=1809599&view=auto
==============================================================================
--- 
sling/site/trunk/content/documentation/bundles/sling-query/hierarchy-operators.mdtext
 (added)
+++ 
sling/site/trunk/content/documentation/bundles/sling-query/hierarchy-operators.mdtext
 Mon Sep 25 10:28:26 2017
@@ -0,0 +1,37 @@
+Title: Hierarchy operators
+
+### Child operator (`parent > child`)
+
+Select all direct child resources specified by `child` of resources specified 
by `parent`
+
+    // find all richtext components placed directly into parsys resources
+    $(resource).find('foundation/components/parsys > 
foundation/components/richtext')
+    // alternative version
+    
$(resource).find('foundation/components/parsys').children('foundation/components/richtext')
+
+### Descendant operator (`ancestor descendant`)
+
+Select all resources that are `descendant`s of a given `ancestor`
+
+    // find all resources containing `someAttribute` on the `cq:Page`s being 
direct children of the resource
+    $(resource).children('cq:Page [someAttribute]')
+    // alternative version
+    $(resource).children('cq:Page').find('[someAttribute]')
+
+### Next adjacent operator (`prev + next`)
+
+Selects all next resources matching `next` that are immediately preceded by a 
sibling `prev`
+
+    // find next sibling of the cq:Page containing the resource
+    $(resource).closest('cq:Page + cq:Page')
+    // alternative version
+    $(resource).closest('cq:Page').next('cq:Page')
+
+### Next siblings operator (`prev ~ next`)
+
+Selects all sibling resources that follow after the `prev` element, have the 
same parent, and match the filtering `siblings` selector
+
+    // find all next siblings of the cq:Page containing the resource
+    $(resource).closest('cq:Page ~ cq:Page')
+    // alternative version
+    $(resource).closest('cq:Page').nextAll('cq:Page')

Added: sling/site/trunk/content/documentation/bundles/sling-query/methods.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/methods.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/methods.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/methods.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,184 @@
+Title: Method list
+
+### `$(Resource... resources)`
+
+Create a new SlingQuery object, using passed resources as an initial 
collection. Example:
+
+    $(resource); // a simple SlingQuery collection containing one resource
+
+### `.add(Resource... resources)`
+
+Add resources to the collection.
+
+    $(resource).children().add(resource); // collection contains resource and 
all its children
+
+### `.asList()`
+
+Transform SlingQuery collection into a lazy list.
+
+    $(resource).children("cq:Page").asList().get(0); // get the first child 
page
+    $(resource).children().asList().isEmpty(); // return true if the resource 
have no children
+
+### `.children([selector])`
+
+Get list of the children for each resource in the collection. Pass `selector` 
to filter children. Example:
+
+    $(resource).children("cq:Page"); // get all page children of the resource
+    $(resource).children().children(); // get all grand-children of the 
resource
+
+### `.closest(selector)`
+
+For each resource in the collection, return the first element matching the 
selector testing the resource itself and traversing up its ancestors. Example:
+
+    $(resource).closest("cq:Page"); // find containing page, like 
PageManager#getContainingPage
+    // let's assume that someCqPageResource is a cq:Page
+    $(someCqPageResource).closest("cq:Page"); // return the same resource
+
+### `.eq(index)`
+
+Reduce resource collection to the one resource at the given 0-based index. 
Example:
+
+    $(resource0, resource1, resource2).eq(1); // return resource1
+    $(resource).children().eq(0); // return first child of the resource
+
+### `.filter(selector)`
+
+Filter resource collection using given selector.
+
+    final Calendar someTimeAgo = Calendar.getInstance();
+    someTimeAgo.add(Calendar.HOUR, -5);
+
+    // get children pages modified in the last 5 hours
+    SlingQuery query = $(resource).children("cq:Page").filter(new 
Predicate<Resource>() {
+        @Override
+        public boolean accepts(Resource resource) {
+            return 
resource.adaptTo(Page.class).getLastModified().after(someTimeAgo);
+        }
+    });
+
+### `.find([selector])`
+
+For each resource in collection return all its descendants using [selected 
strategy](#searchstrategystrategy). Please notice that invoking this method on 
a resource being a root of a large subtree may and will cause performance 
problems.
+
+    $(resource).find("cq:Page"); // find all descendant pages
+
+### `.first()`
+
+Filter resource collection to the first element. Equivalent to `.eq(0)` or 
`.slice(0, 0)`.
+
+    $(resource).siblings().first(); // get the first sibling of the current 
resource
+
+### `.has(selector)`
+
+Pick such resources from the collection that have descendant matching the 
selector. Example:
+
+    $(...).children('cq:Page').has(foundation/components/richtext) // find 
children pages containing some richtext component
+
+This method uses [selected strategy](#searchstrategystrategy) to iterate over 
resource descendants.
+
+### `.last()`
+
+Filter resource collection to the last element.
+
+    $(resource).siblings().last(); // get the last sibling of the current 
resource
+
+### `.map(Class<T> clazz)`
+
+Transform the whole collection to a new `Iterable<T>` object, invoking 
`adaptTo(clazz)` method on each resource. If some resource can't be adapted to 
the class (eg. `adaptTo()` returns `null`), it will be skipped. Example:
+
+    for (Page page : $(resource).parents("cq:Page").map(Page.class)) {
+        // display breadcrumbs
+    }
+
+### `.next([selector])`
+
+Return the next sibling for each resource in the collection and optionally 
filter it by a selector. If the selector is given, but the sibling doesn't 
match it, empty collection will be returned.
+
+    // let's assume that resource have 3 children: child1, child2 and child3
+    $(resource).children().first().next(); // return child2
+
+### `.nextAll([selector])`
+
+Return all following siblings for each resource in the collection, optionally 
filtering them by a selector.
+
+    // let's assume that resource have 3 children: child1, child2 and child3
+    $(resource).children().first().nextAll(); // return child2 and child3
+
+### `.nextUntil(selector)`
+
+Return all following siblings for each resource in the collection up to, but 
not including, resource matched by a selector.
+
+    // let's assume that resource have 4 children: child1, child2, child3 and 
child4
+    // additionaly, child4 has property jcr:title=Page
+    $(resource).children().first().nextUntil("[jcr:title=Page]"); // return 
child2 and child3
+
+### `.not(selector)`
+
+Remove elements from the collection.
+
+    $(resource).children().not("cq:Page"); // remove all cq:Pages from the 
collection
+    $(resource).children().not(":first").not(":last"); // remove the first and 
the last element of the collection
+
+### `.parent()`
+
+Replace each element in the collection with its parent.
+
+    $(resource).find("cq:PageContent[jcr:title=My page]:first").parent(); // 
find the parent of the first `cq:PageContent` resource with given attribute in 
the subtree
+    
+### `.parents([selector])`
+
+For each element in the collection find all of its ancestors, optionally 
filtering them by a selector.
+
+    ($resource).parents("cq:Page"); // create page breadcrumbs for the given 
resources
+
+### `.parentsUntil(selector)`
+
+For each element in the collection find all of its ancestors until a resource 
matching the selector is found.
+
+    ($currentResource).parentsUntil("cq:Page"); // find all ancestor 
components on the current page
+    
+### `.prev([selector])`
+
+Return the previous sibling for each resource in the collection and optionally 
filter it by a selector. If the selector is given, but the sibling doesn't 
match it, empty collection will be returned.
+
+    // let's assume that resource have 3 children: child1, child2 and child3
+    $(resource).children().last().prev(); // return child2
+
+### `.prevAll([selector])`
+
+Return all preceding siblings for each resource in the collection, optionally 
filtering them by a selector.
+
+    // let's assume that resource have 3 children: child1, child2 and child3
+    $(resource).children().last().prevAll(); // return child1 and child2
+
+### `.prevUntil(selector)`
+
+Return all preceding siblings for each resource in the collection up to, but 
not including, resource matched by a selector.
+
+    // let's assume that resource have 4 children: child1, child2, child3 and 
child4
+    // additionally, child1 has property jcr:title=Page
+    $(resource).children().last().prevUntil("[jcr:title=Page]"); // return 
child2 and child3
+
+### `.searchStrategy(strategy)`
+
+Select new search strategy, which will be used in following 
[`find()`](#findselector) and [`has()`](#hasselector) function invocations. 
There 3 options:
+
+* `SearchStrategy.DFS` - [depth-first 
search](http://en.wikipedia.org/wiki/Depth-first_search)
+* `SearchStrategy.BFS` - [breadth-first 
search](http://en.wikipedia.org/wiki/Breadth-first_search)
+* `SearchStrategy.QUERY` - use JCR SQL2 query (default since 1.4.0)
+
+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.
+
+### `.siblings([selector])`
+
+Return siblings for the given resources, optionally filtered by a selector.
+
+    $(resource).closest("cq:Page").siblings("cq:Page"); // return all sibling 
pages
+
+### `.slice(from[, to])`
+
+Reduce the collection to a sub-collection specified by a given range. Both 
`from` and `to` are inclusive and 0-based indices. If the `to` parameter is not 
specified, the whole sub-collection starting with `from` will be returned.
+
+    // let's assume that resource have 4 children: child1, child2, child3 and 
child4
+    $(resource).children().slice(1, 2); // return child1 and child2
+

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/modifiers.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/modifiers.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/modifiers.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/modifiers.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,61 @@
+Title: Modifiers
+
+### `:eq(index)`
+
+Reduce the set of matched elements to the one at the specified 0-based index. 
Example:
+
+    $(...).find("foundation/components/richtext:eq(2)"); // find the third 
richtext in the subtree
+
+### `:even`
+
+Reduce the set of matched elements to those which indexes are even numbers:
+
+    $(...).children("cq:Page:even"); // get even children pages for each 
resource in the collection
+
+### `:first`
+
+Reduce the set of matched elements to the first one:
+
+    $(...).find("foundation/components/richtext:first"); // find the first 
richtext in the subtree
+
+### `:gt(index)`
+
+Reduce the set of matched elements to those which indexes are greater than the 
argument:
+
+    $(...).children("cq:Page:gt(2)"); // filter out first 3 pages
+
+### `:has(selector)`
+
+Reduce the set of the matched elements to those which have descendant matching 
the selector:
+
+    $(...).children("cq:Page:has(foundation/components/richtext)]"); // get 
children pages containing richtext component
+
+### `:last`
+
+Reduce the set of matched elements to the last one:
+
+    $(...).find("foundation/components/richtext:last"); // find the last 
richtext in the subtree
+
+### `:lt(index)`
+
+Reduce the set of matched elements to those which indexes are lesser than the 
argument:
+
+    $(...).children("cq:Page:lt(3)"); // get first 3 matches
+
+### `:not(selector)`
+
+Reduce the set of matched elements to those which doesn't match the selector. 
The selector may contain other modifiers as well, however in this case the 
function will be evaluated eagerly:
+
+    $(...).find(":not(:parent)"); // ancestor resources that doesn't contain 
any children
+
+### `:odd`
+
+Reduce the set of matched elements to those which indexes are odd numbers:
+
+    $(...).children("cq:Page:odd"); // get odd children pages for each 
resource in the collection
+
+### `:parent`
+
+Reduce the set of the matched elements to those which have any descendant 
resource.
+
+    $(...).children(":parent]"); // get children resources containing any 
resource

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/operators.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/operators.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/operators.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/operators.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,47 @@
+Title: Operators
+
+### Contains `[name*=value]`
+
+Select resources that have property `name` containing `value`:
+
+    // select children pages titled 'foo', 'foo bar', 'bar foo bar', 
'foofoofoo', etc.
+    $(resources).children("cq:Page[jcr:content/jcr:title*=foo]")
+
+### Contains a word `[name~=value]`
+
+Select resources that have property `name` containing word `value` delimited 
with spaces:
+
+    // select children pages titled 'foo', 'foo bar', 'bar foo bar', but not 
'foofoofoo'
+    $(resources).children("cq:Page[jcr:content/jcr:title~=foo]")
+
+### Ends with `[name$=value]`
+
+Select resources that have property `name` ending with `value`:
+
+    // select children pages titled 'foo', 'bar foo', etc.
+    $(resources).children("cq:Page[jcr:content/jcr:title$=foo]")
+
+### Equals `[name=value]`
+
+Select resources that have property `name` that equals to `value`:
+
+    $(resources).children("cq:Page[jcr:content/jcr:title=foo]")
+
+### Not equal `[name!=value]`
+
+Select resources that have property `name` that not equals to `value`:
+
+    $(resources).children("cq:Page[jcr:content/jcr:title!=foo]")
+
+### Starts with `[name^=value]`
+
+Select resources that have property `name` starting with `value`:
+
+    // select children pages titled 'foo', 'foo bar', etc.
+    $(resources).children("cq:Page[jcr:content/jcr:title^=foo]")
+
+### Has attribute `[name]`
+
+Select resources that have property `name`:
+
+    $(resources).find("[markerProperty]")

Added: 
sling/site/trunk/content/documentation/bundles/sling-query/selectors.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/selectors.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/selectors.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/selectors.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,67 @@
+Title: Selectors
+
+Selector string are something between filters and content descriptors. 
Selector can filter resources by their [type](#resource-type), 
[name](#resource-name), [attributes](#attributes) and [additional 
modifiers](#modifiers). They can be also [chained together](#joining-selectors) 
to describe more sophisticated hierarchy structure or [combined with 
comma](#combining-selectors).
+
+## Syntax
+
+Selector consists of four parts:
+
+### Resource type
+
+Resource type, which could be a `sling:resourceType`, like 
`foundation/components/richtext` or the underlying JCR node type, like 
`cq:Page` or `nt:unstructured`. In the latter case, SlingQuery takes types 
hierarchy into consideration (eg. `nt:base` matches everything). JCR mixin 
types could be used as well.
+
+### Resource name
+
+Resource name can be defined with a hash `#` character, after the resource 
type (or instead of it):
+
+    $(resource).children("cq:Page#some-name")
+
+If the desired resource name contains colon (`:`) character, the whole string 
should be escaped with apostrophes:
+
+    $(resource).children("#'jcr:content'[jcr:title=My title]")
+
+### Attributes
+
+After the resource type and resource name one could pass a number of filtering 
attributes. Each attribute has following form: `[property=value]`. Passing 
multiple attributes will match only those resources that have all of them set. 
Property name could contain `/`. In this case property will be taken from the 
child resource, eg.:
+
+    $(resource).children("cq:Page[jcr:content/jcr:title=My title]")
+    
+will return only children of type `cq:Page` that have sub-resource called 
`jcr:content` with property `jcr:title` set to `My title`. Besides the `=` you 
may use other operators like `*=`, which means *contains*:
+
+    $(resource).children("cq:Page[jcr:content/jcr:title*=title]")
+
+See the [fulll list of operators](Operator list).
+
+### Modifiers
+
+At the end of the selector one could define any number of modifiers that will 
be used to filter out the resources matched by the resource type and 
attributes. Each modifier starts with colon, some of them accepts a parameter 
set in parentheses. Example:
+
+    $(resource).children("cq:Page:first");
+    $(resource).children("cq:Page:eq(0)"); // the same
+    $(resource).children(":first"); // modifier can be used alone
+
+It is important that modifier filters out sub-collection created for each 
node, before it is merged. Eg.:, there is a difference between:
+
+    $(resource1, resource2).children().first();
+
+and
+
+    $(resource1, resource2).children(":first");
+    
+In the first case we create a new collection consisting of children of the 
`resource1` and `resource2` and then we get the first element of the merged 
collection. On the other hand, the second example takes *first child* of each 
resource and creates a collection from them.
+
+See the [full list of modifiers](Modifier list).
+
+## Joining selectors
+
+Selectors can be joined together using [hierarchy operators](Hierarchy 
operator list). This feature enables the developer to create sophisticated 
filters describing desired resource structure, eg.:
+
+    $(resource).children("cq:Page foundation/components/parsys > 
foundation/components/richtext")
+
+will all `cq:Page`s containing paragraph systems with a richtext inside.
+
+## Combining selectors
+
+You may specify any number of selectors to combine into a single result. Use 
comma to join a few conditions. Comma is treated as `OR` statement:
+
+    $(resource).children("#en, #de, #fr"); // return all direct children named 
`en` or `de` or `fr`.

Added: sling/site/trunk/content/documentation/bundles/sling-query/vs-jcr.mdtext
URL: 
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/sling-query/vs-jcr.mdtext?rev=1809599&view=auto
==============================================================================
--- sling/site/trunk/content/documentation/bundles/sling-query/vs-jcr.mdtext 
(added)
+++ sling/site/trunk/content/documentation/bundles/sling-query/vs-jcr.mdtext 
Mon Sep 25 10:28:26 2017
@@ -0,0 +1,17 @@
+Title: Sling Query vs JCR
+
+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.
+
+Purpose of the SlingQuery is to provide a convenient way to traverse resource 
tree. All SlingQuery operations are eventually transformed into a series of 
`listChildren()` and `getParent()` operations [1].
+
+As a rule of thumb - if you have a complex Java loop reading resource children 
or parents and processing them somehow, rewritting it to SlingQuery will be a 
good choice. If you have a recursive method trying to get some resource 
ancestor, using SlingQuery will be a good choice. On the other hand, if you 
have a large resource subtree and want to find all `cq:Page`s, using SlingQuery 
is a bad choice.
+
+| Description                                           | JCR query | 
SlingQuery |
+| 
------------------------------------------------------|-----------|------------|
+| You have a complex logic using Sling Resource API     | -         | Yes!     
  |
+| You want to find resource ancestor                    | -         | Yes!     
  |
+| You want to find all descendants with given attribute | Yes!      | -        
  |
+| You want to find all descendants of given type        | Yes!      | -        
  |
+| You'd like to get ordered results                     | Yes!      | -        
  |
+
+[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](Method 
list#searchstrategystrategy) for more details.


Reply via email to