All Implemented Interfaces:
NamedWriteable, Writeable, PostAnalysisVerificationAware, PostOptimizationPlanVerificationAware, TelemetryAware, Resolvable, ExecutesOn, ExecutesOn.Coordinator

Logical plan for the MMR command. MMR performs result diversification on incoming results using maximum marginal relevance. The input is a set of limited rows, where at least one field is a dense vector to use for vector comparison. The output is a reduced set of results, in the same order as the input, but "diversified" to be results that are semantically diverse from each other within the input set.
  • Field Details

  • Constructor Details

  • Method Details

    • diversifyField

      public Attribute diversifyField()
    • limit

      public Expression limit()
    • queryVector

      public Expression queryVector()
    • options

      public MapExpression options()
    • replaceChild

      public UnaryPlan replaceChild(LogicalPlan newChild)
      Specified by:
      replaceChild in class UnaryPlan
    • expressionsResolved

      public boolean expressionsResolved()
      Specified by:
      expressionsResolved in class LogicalPlan
    • info

      protected NodeInfo<? extends LogicalPlan> info()
      Description copied from class: Node
      Normally, you want to use one of the static create methods to implement this.

      For QueryPlans, it is very important that the properties contain all of the expressions and references relevant to this node, and that all the properties are used in the provided constructor; otherwise query plan transformations like QueryPlan#transformExpressionsOnly(Function) will not have an effect.

      Specified by:
      info in class Node<LogicalPlan>
    • getWriteableName

      public String getWriteableName()
      Specified by:
      getWriteableName in interface NamedWriteable
    • writeTo

      public void writeTo(StreamOutput out) throws IOException
      Specified by:
      writeTo in interface Writeable
      Throws:
      IOException
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class UnaryPlan
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class UnaryPlan
    • postAnalysisVerification

      public void postAnalysisVerification(Failures failures)
      Description copied from interface: PostAnalysisVerificationAware
      Allows the implementer to validate itself. This usually involves checking its internal setup, which often means checking the parameters it received on construction: their data or syntactic type, class, their count, expressions' structure etc. The discovered failures are added to the given Failures object.

      It is often more useful to perform the checks as extended as it makes sense, over stopping at the first failure. This will allow the author to progress faster to a correct query.

      Example: the Filter class, which models the WHERE command, checks that the expression it filters on - condition - is of a Boolean or NULL type:

           
           @Override
           void postAnalysisVerification(Failures failures) {
                if (condition.dataType() != NULL && condition.dataType() != BOOLEAN) {
                    failures.add(fail(condition, "Condition expression needs to be boolean, found [{}]", condition.dataType()));
                }
           }
           
           
      Specified by:
      postAnalysisVerification in interface PostAnalysisVerificationAware
      Parameters:
      failures - the object to add failures to.
    • postOptimizationPlanVerification

      public BiConsumer<LogicalPlan,Failures> postOptimizationPlanVerification()
      Description copied from interface: PostOptimizationPlanVerificationAware
      Validates the implementing expression - discovered failures are reported to the given Failures class.

      Example: the SORT command, OrderBy, can only be executed currently if it can be associated with a LIMIT Limit and together transformed into a TopN (which is executable). The replacement of the LIMIT+SORT into a TopN is done at the end of the optimization phase. This means that any SORT still existing in the plan post optimization is an error. However, there can be a LIMIT in the plan, but separated from the SORT by an INLINE STATS; in this case, the LIMIT cannot be pushed down near the SORT. To inform the user how they need to modify the query so it can be run, we implement this:

           
      
            @Override
            public BiConsumer<LogicalPlan, Failures> postOptimizationPlanVerification() {
                return (p, failures) -> {
                    if (p instanceof InlineJoin inlineJoin) {
                        inlineJoin.forEachUp(OrderBy.class, orderBy -> {
                            failures.add(
                                fail(
                                    inlineJoin,
                                    "unbounded SORT [{}] not supported before INLINE STATS [{}], move the sort after the INLINE STATS",
                                    orderBy.sourceText(),
                                    inlineJoin.sourceText()
                                )
                            );
                        });
                    } else if (p instanceof OrderBy) {
                        failures.add(fail(p, "Unbounded SORT not supported yet [{}] please add a LIMIT", p.sourceText()));
                    }
                };
            }
           
           

      If we didn't need to check the structure of the plan, it would have sufficed to implement the PostOptimizationVerificationAware interface, which would simply check if there is an instance of OrderBy in the plan.

      Specified by:
      postOptimizationPlanVerification in interface PostOptimizationPlanVerificationAware
      Returns:
      a consumer that will receive a tree to check and an accumulator of failures found during inspection.