com.day.cq.search.eval
Interface PredicateEvaluator

All Known Implementing Classes:
AbstractPredicateEvaluator, DateRangePredicateEvaluator, FulltextPredicateEvaluator, JcrPropertyPredicateEvaluator, NodenamePredicateEvaluator, PathPredicateEvaluator, PredicateGroupEvaluator, RangePropertyPredicateEvaluator, RootEvaluator, SimilarityPredicateEvaluator, TypePredicateEvaluator

public interface PredicateEvaluator

A PredicateEvaluator handles the evaluation of certain Predicates, which are the defining constraint of a Query. Each evaluator handles a certain type of Predicates, which is given by Predicate.getType(). Generally speaking, it maps a higher-level search constraint, such as "width > 200", to a specific JCR query that fits the actual content model, eg. metadata/@width > 200. XPath is the query language of choice here, and the XPath predicate expression must be returned in #getXPathExpression(Session).

If the constraint of this PredicateEvaluator cannot be formulated via a JCR XPath predicate expression, the result can also be filterd using the #includes(Row) method. Please note that filtering is more likely to negatively impact performance, so try to reduce the original result set using #getXPathExpression(Session) as much as possible.

In addition, since facets in the search result will always match to what constraints you can put in a query, a PredicateEvaluator also provides a FacetExtractor that creates its facet based on the search result. The #getFacetExtractor() method returns the extractor that will afterwards run over the result set to find any facets.

Implementations of this interface must either be defined as OSGi components (to be used for any query) or registered explicitly for a certain query using Query.registerPredicateEvaluator(String, PredicateEvaluator). If the OSGi component way is chosen, the component must be defined as a component factory. The name of the factory must be the fully qualified name of this interface plus "/" and the type of the predicate this evaluator will be used for. For example for a PredicateEvaluator handling the predicate type "fulltext", the SCR javadoc tag would look like this:

 @scr.component metatype="no" factory="com.day.cq.search.eval.PredicateEvaluator/fulltext"
 

Since:
5.2

Method Summary
 FacetExtractor getFacetExtractor(Predicate predicate, EvaluationContext context)
          Returns a FacetExtractor that is used to create a Facet that maps to the given predicate.
 Comparator<Row> getOrderByComparator(Predicate predicate, EvaluationContext context)
          Returns a comparator that will be used to "manually" sort the result after running the xpath query and after filtering via includes(Predicate, Row, EvaluationContext) happened.
 String[] getOrderByProperties(Predicate predicate, EvaluationContext context)
          Returns a list of JCR property names or relative paths (see note below!) to properties that should be used when the result should be ordered by the given predicate.
 String getXPathExpression(Predicate predicate, EvaluationContext context)
          Returns an XPath predicate expression, which is just a partial expression that can be placed inside "[" and "]" in a full XPath statement.
 boolean includes(Predicate predicate, Row row, EvaluationContext context)
          If the constraint for the given predicate formulated via a JCR XPath expression, this method can be used to filter the result set row by row (to get the node behind the row, one can use context.getNode(row).
 boolean isFiltering(Predicate predicate, EvaluationContext context)
          Returns true if the evaluator will actually handle the predicate in some way in the includes(Predicate, Row, EvaluationContext) method.
 

Method Detail

getXPathExpression

String getXPathExpression(Predicate predicate,
                          EvaluationContext context)
Returns an XPath predicate expression, which is just a partial expression that can be placed inside "[" and "]" in a full XPath statement. Examples are:
 @jcr:title = 'Foobar'
 
or this longer expression:
 (@count > 10 and @count < 20) or @state = 'foo'
 

As a different constraint, an implementation can also filter the result of the query, using the #includes(Node) method.

Note that an implementation must return an empty string or null if its parameters are empty, ie. if the predicate should not "take part" in the actual query. This is because we need to keep track of the potential predicates for the query to get all Facets, not only the ones for what is already queried.

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
context - helper class which provides access to various elements of the query evaluation
Returns:
string containing an XPath predicateEvaluator expression

getOrderByProperties

String[] getOrderByProperties(Predicate predicate,
                              EvaluationContext context)
Returns a list of JCR property names or relative paths (see note below!) to properties that should be used when the result should be ordered by the given predicate. The paths will be used in the order by part of the Xpath query (in the given order). Can return null if there is no property to order by. Additional ordering can happen by returning a custom Comparator in getOrderByComparator(Predicate, EvaluationContext).

Important note: For relative paths, eg. jcr:content/jcr:lastModified, this currently (CQ 5.2 / CRX 1.4.2) requires an according indexing configuration in CRX, because child axis support for the order by clause is only available for content that was indexed explicitly for that use case, ie. if you have existing content and want to use a new relative path for order by, changing the indexing config *and* reindexing the content is required. This is a special, temporary feature in CRX 1.4.2 - the next major CRX release will have a generic support for that. However, indexing speeds up the ordering. Below are the notes from the according bug #21311; the indexing config in a standard CQ 5.2 installation can be found under INSTALL_DIR/crx-quickstart/server/runtime/0/_crx/WEB-INF/classes/indexing_config.xml.

 Please note that this change will *not* go into CRX trunk! Proper support for
 this feature will be implemented in Jackrabbit 1.6. See also:
 https://issues.apache.org/jira/browse/JCR-800
 
 Notes on usage:
 
 The include element of an aggregate now also takes a relative path to a property.
 The referenced property will be indexed as a pseudo property on the aggregate
 root node and can be used in the order by clause.
 
 E.g.:
 
 <?xml version="1.0"?>
 <!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">
 <configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
                xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
   <aggregate primaryType="nt:file">
     <include>jcr:content</include>
     <include>jcr:content/jcr:lastModified</include>
   </aggregate>
 </configuration>
 
 This will create a pseudo property jcr_content_jcr_lastModified on the nt:file
 node and allows you to order nt:file nodes by the last modified date:
 
 //element(*, nt:file) order by @jcr_content_jcr_lastModified
 
 Please note that the relative path is normalized. That is, colons and slashes
 are replaced with underscores. (This only applies for raw XPath queries, the
 OderByPredicateEvaluator will handle that automatically, ie. you always use
 proper paths in the "oderby" parameter).
 
 Known limitations:
 
 - You need to add an include on the aggregate for the parent node of the
 property that you want to sort on. In the above example, that's jcr:content.
 
 - Wildcards are not allowed for includes that reference properties.
 

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
context - helper class which provides access to various elements of the query evaluation
Returns:
one or multiple relative paths to JCR properties or null

isFiltering

boolean isFiltering(Predicate predicate,
                    EvaluationContext context)
Returns true if the evaluator will actually handle the predicate in some way in the includes(Predicate, Row, EvaluationContext) method. This is required to separate evaluators that always return true in includes(Predicate, Row, EvaluationContext), because they don't do any filtering, from those that filter the result set and also return true.

Note that this should return false if the predicate is "empty", eg. is not providing any required paramters.

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
context - helper class which provides access to various elements of the query evaluation
Returns:
true if this evaluator is filtering the result set for the given predicate

includes

boolean includes(Predicate predicate,
                 Row row,
                 EvaluationContext context)
If the constraint for the given predicate formulated via a JCR XPath expression, this method can be used to filter the result set row by row (to get the node behind the row, one can use context.getNode(row).

Please note that this is more likely to negatively impact performance, so try to reduce the original result set using #getXPathExpression(Session) as much as possible.

If you implement this method, don't forget to implement isFiltering(Predicate, EvaluationContext).

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
row - current row of the result set returned through the xpath query
context - helper class which provides access to various elements of the query evaluation
Returns:
true if this row should be part of the final result set, false if it should be dropped

getOrderByComparator

Comparator<Row> getOrderByComparator(Predicate predicate,
                                     EvaluationContext context)
Returns a comparator that will be used to "manually" sort the result after running the xpath query and after filtering via includes(Predicate, Row, EvaluationContext) happened. This can be expensive and if possible, getOrderByProperties(Predicate, EvaluationContext) (which is used for XPath order by) should be used. Result can be null.

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
context - helper class which provides access to various elements of the query evaluation
Returns:
a custom comparator for the given predicate or null

getFacetExtractor

FacetExtractor getFacetExtractor(Predicate predicate,
                                 EvaluationContext context)
Returns a FacetExtractor that is used to create a Facet that maps to the given predicate. There are built-in extractor implementations that can be used (eg. DistinctValuesFacetExtractor which automatically creates a Facet with buckets based on the distinct values of a certain property).

This method will only be called when the API user actually requests the facets from the search result using SearchResult.getFacets().

Important note: this object as OSGi component instance will be released before this method is called; it will be released directly after executing the query, because it cannot be known if SearchResult.getFacets() will be called. This means that all OSGi references that the implementing object defines will be lost, ie. they will have the value null.

Parameters:
predicate - predicate (for this evaluator type) which is evaluated
context - helper class which provides access to various elements of the query evaluation
Returns:
a FacetExtractor that is used to create a Facet or null if no extractor shall be provided


Copyright © 2009 Day Management AG. All Rights Reserved.