Interface PredicateEvaluator

All Known Implementing Classes:
AbstractPredicateEvaluator, AssetRenditionFilterPredicateEvaluator, CollectionPredicateEvaluator, DateRangePredicateEvaluator, FulltextPredicateEvaluator, JcrBoolPropertyPredicateEvaluator, JcrPropertyPredicateEvaluator, NodenamePredicateEvaluator, PathPredicateEvaluator, PermissionPredicateEvaluator, PredicateGroupEvaluator, RangePropertyPredicateEvaluator, RelativeDateRangePredicateEvaluator, SavedQueryPredicate, SimilarityPredicateEvaluator, SubAssetFilterPredicateEvaluator, TypePredicateEvaluator

public interface PredicateEvaluator
A 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/fulltextinvalid input: '&quot')
 
Since:
5.2
  • Method Details

    • 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(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.

      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
    • 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!

      If you implement this method, don't forget to implement canFilter(Predicate, EvaluationContext) so that it returns true.

      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
    • canXpath

      boolean canXpath(Predicate predicate, EvaluationContext context)
      Returns whether this evaluator can return its constraint via xpath, ie. 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.

      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 can express itself via xpath, ie. getXPathExpression(Predicate, EvaluationContext)
      Since:
      5.3
    • canFilter

      boolean canFilter(Predicate predicate, EvaluationContext context)
      Returns whether this evaluator can handle its constraint via filtering, ie. 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.

      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 can be express itself via filtering, ie. includes(Predicate, Row, EvaluationContext)
      Since:
      5.3
    • 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 parameters.

      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
    • getOrderByProperties

      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. 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).
      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
    • 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 (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).

      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