@ConsumerType
public interface PredicateEvaluator
PredicateEvaluator
handles the evaluation of certain
Predicates
, which are the defining constraints 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
, or it can manually filter nodes and look
at them to check its constraint.
Xpath vs. Filtering: XPath is the query language of choice here, and
the XPath predicate expression must be returned in
getXPathExpression(Predicate, EvaluationContext)
. If the constraint
of this evaluator cannot be formulated via a JCR XPath predicate expression,
the result can also be filtered using the
includes(Predicate, Row, EvaluationContext)
method. Please note that
filtering is more likely to negatively impact performance, so xpath is the
preferred way.
Important Note: It is recommended that evaluators implement their concept via xpath and filtering (ie. two different implementations of the same constraint), or via filtering only. This is because in the case of predicate groups that are combined with OR, and at least one of the predicates is done only via filtering, the whole group must be done via filtering. Filtering itself cannot add new nodes to the result, so the whole group must not produce any xpath constraint that would reduce the set "too much" before filtering. Not complying to this recommendation will make xpath-only predicates not work inside mixed or groups, but can still work for other scenarios.
Ordering: To sort the result set, an evaluator can either specify one
or more JCR properties via
getOrderByProperties(Predicate, EvaluationContext)
or provide a
custom comparator that works on the final result set via
getOrderByComparator(Predicate, EvaluationContext)
.
Facets: A PredicateEvaluator
also provides a
FacetExtractor
that creates buckets based on the search result, since
facets will conceptually always match to the types of constraints you can put
in a query. The getFacetExtractor(Predicate, EvaluationContext)
method returns the extractor that will afterwards run over the result set to
find any facets.
Registration: 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. Names should not start with a "_", as they will be ignored for
queries created from requests (see
PredicateConverter.createPredicates(java.util.Map)
. 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
annotation would look like this:
@Component(metatype = false, factory="com.day.cq.search.eval.PredicateEvaluator/fulltext")
Modifier and Type | Method and Description |
---|---|
boolean |
canFilter(Predicate predicate,
EvaluationContext context)
Returns whether this evaluator can handle its constraint via filtering,
ie.
|
boolean |
canXpath(Predicate predicate,
EvaluationContext context)
Returns whether this evaluator can return its constraint via xpath, ie.
|
FacetExtractor |
getFacetExtractor(Predicate predicate,
EvaluationContext context)
Returns a
FacetExtractor that is used to create a Facet
that maps to the given predicate. |
java.util.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. |
java.lang.String[] |
getOrderByProperties(Predicate predicate,
EvaluationContext context)
Returns a list of JCR property names or relative paths
to properties that should be used when the result should be ordered by
the given predicate.
|
java.lang.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)
Deprecated.
Since 5.3, use
canFilter(Predicate, EvaluationContext) and
canXpath(Predicate, EvaluationContext) instead. |
java.lang.String getXPathExpression(Predicate predicate, EvaluationContext context)
@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(Predicate, Row, EvaluationContext)
method. Also, it is
recommended to implement the xpath-based constraint again inside
includes() to
support the case where filtering is forced by a parent predicte group.
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.
If you implement this method, don't forget to implement
canXpath(Predicate, EvaluationContext)
so that it returns true.
predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationboolean includes(Predicate predicate, Row row, EvaluationContext context)
context.getNode(row)
.
Please note that this is more likely to negatively impact performance!
If you implement this method, don't forget to implement
canFilter(Predicate, EvaluationContext)
so that it returns true.
predicate
- predicate (for this evaluator type) which is evaluatedrow
- current row of the result set returned through the xpath querycontext
- helper class which provides access to various elements of the
query evaluationtrue
if this row should be part of the final result
set, false
if it should be droppedboolean canXpath(Predicate predicate, EvaluationContext context)
getXPathExpression(Predicate, EvaluationContext)
.
Note that the result typically does not depend on either the predicate or the context (given as parameters) - in most cases this depends directly on the implementation.
predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationtrue
if this evaluator can express itself via xpath,
ie. getXPathExpression(Predicate, EvaluationContext)
boolean canFilter(Predicate predicate, EvaluationContext context)
includes(Predicate, Row, EvaluationContext)
.
Note that the result typically does not depend on either the predicate or the context (given as parameters) - in most cases this depends directly on the implementation.
predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationtrue
if this evaluator can be express itself via
filtering, ie.
includes(Predicate, Row, EvaluationContext)
boolean isFiltering(Predicate predicate, EvaluationContext context)
canFilter(Predicate, EvaluationContext)
and
canXpath(Predicate, EvaluationContext)
instead.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 parameters.
predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationtrue
if this evaluator is filtering the result set
for the given predicatejava.lang.String[] getOrderByProperties(Predicate predicate, EvaluationContext context)
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)
.predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationnull
java.util.Comparator<Row> getOrderByComparator(Predicate predicate, EvaluationContext context)
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
.predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationnull
FacetExtractor getFacetExtractor(Predicate predicate, EvaluationContext context)
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 (the PredicateEvaluator) as an OSGi
component instance will be released before the returned FacetExtractor is
used, ie. before any method is called on it. This lazy usage of the
extractor is needed, because during query execution it cannot be known if
SearchResult.getFacets()
will be called by the client afterwards.
Thus be careful if you return an inner or anonymous class that uses
members of this evaluator which are references to other OSGi components -
at the time of facet extraction, these will be effectively
null
. Thus you should retrieve information from the service
while this method is called and store the result in the returned
FacetExtractor object. This also means that you cannot directly use OSGi
references in a FacetExtractor at all (they are not OSGi components).
predicate
- predicate (for this evaluator type) which is evaluatedcontext
- helper class which provides access to various elements of the
query evaluationFacetExtractor
that is used to create a Facet
or null
if no extractor shall be providedCopyright © 2010 - 2020 Adobe. All Rights Reserved