Make search functions translation aware#118355
Conversation
| @SuppressWarnings("rawtypes") | ||
| @Override | ||
| protected ExpressionTranslator translator() { | ||
| return new EsqlExpressionTranslators.KqlFunctionTranslator(); |
There was a problem hiding this comment.
I guess we could move the translators from EsqlExpressionTranslators but for now I just leave them as they are - I wasn't sure we need to move them. happy to hear otherwise.
There was a problem hiding this comment.
My preference is to move them, but not in this PR - as a follow up.
| @SuppressWarnings("rawtypes") | ||
| protected abstract ExpressionTranslator translator(); | ||
|
|
||
| public abstract Expression replaceQueryBuilder(QueryBuilder queryBuilder); |
There was a problem hiding this comment.
this is not used yet - but this is what we will call for the query rewrite phase - see #118106
ChrisHegarty
left a comment
There was a problem hiding this comment.
Overall, I think that this is a good refactoring and improvement that will facilitate better encapsulation and reuse of existing builders. LGTM
| @SuppressWarnings("rawtypes") | ||
| @Override | ||
| protected ExpressionTranslator translator() { | ||
| return new EsqlExpressionTranslators.KqlFunctionTranslator(); |
There was a problem hiding this comment.
My preference is to move them, but not in this PR - as a follow up.
...n/java/org/elasticsearch/xpack/esql/core/querydsl/query/TranslationAwareExpressionQuery.java
Show resolved
Hide resolved
...n/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TranslationAware.java
Show resolved
Hide resolved
|
Pinging @elastic/es-analytical-engine (Team:Analytics) |
| * {@link Query} translation, instead of relying on the registered translators from EsqlExpressionTranslators. | ||
| */ | ||
| public interface TranslationAware { | ||
| Query asQuery(TranslatorHandler translatorHandler); |
There was a problem hiding this comment.
I think it would make sense to centralize in this interface all the pushdown logic, including
- capabilities, eg. can it be pushed down to Lucene at all? Maybe sometimes it depends on its inputs?
- constraints, eg. does this function need to be pushed down to be executed? Does it also have an inline implementation that works without pushdown?
The first point is covered by PushFiltersToSource physical rule. I'm not sure if we want ad-hoc logic for each function or if we can simplify it to a single and generic behavior (ie. removing the if (exp instanceof Term). In both cases I'd rather have an exp instanceof TranslationAware there, so that one day we can also let other operators/functions implement it and remove that long list of instanceofs.
For the second point I'm thinking about the Verifier logic around FullTextFunctions. It's a complex topic that involves some deep understanding of how commands interact with each other, I put it here for completeness but probably we can address it in a follow-up PR
There was a problem hiding this comment.
thank you for the review!
For the first point the PushFiltersToSource we need to look into it but I think we don't need the condition for Term - we removed a similar one for Match - see https://github.com/elastic/elasticsearch/pull/117555/files#r1858385620
For the second point, agreed we can do it in a follow up - I think it would be a big enough change that we would want to review separately.
fang-xing-esql
left a comment
There was a problem hiding this comment.
Thank you @ioanatia. It is a good step forward to add TranslationAware. I added a few things that I can think of so far.
| return Objects.equals(queryBuilder, ((FullTextFunction) obj).queryBuilder); | ||
| } | ||
|
|
||
| @SuppressWarnings("rawtypes") |
There was a problem hiding this comment.
Add a @Override annotation here.
| return new TranslationAwareExpressionQuery(source(), queryBuilder); | ||
| } | ||
|
|
||
| ExpressionTranslator translator = translator(); |
There was a problem hiding this comment.
If ExpressionTranslator<? extends FullTextFunction> is used here, the @SuppressWarnings("rawtypes") can go away. The same applies to the translator() of the five FullTextFunctions.
| public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Kql", Kql::new); | ||
| public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Kql", Kql::readFrom); | ||
|
|
||
| public Kql(Source source, Expression queryString, QueryBuilder queryBuilder) { |
There was a problem hiding this comment.
Can this be private? And it looks better(to me) if this is after the constructor with FunctionInfo. The same applies to the other three - Match, QueryString and Term.
There was a problem hiding this comment.
I made them private and then the EsqlNodeSubclassTests started failing because AFAICT they expect that the argument number from the longest public constructor to correlate with the number of args from NodeInfo.
This to me seems to be a quirk of the EsqlNodeSubclassTests rather than a test catching a real bug with FullTextFunctions
...rc/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextFunction.java
Show resolved
Hide resolved
* Introduce TranslationAware interface * Serialize query builder * Fix EsqlNodeSubclassTests * Add javadoc * Address review comments * Revert changes on making constructors private
* Introduce TranslationAware interface * Serialize query builder * Fix EsqlNodeSubclassTests * Add javadoc * Address review comments * Revert changes on making constructors private Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Following up on #118106 - we break adding semantic search in ES|QL into multiple parts:
This is just taking care of (1). We introduce a
TranslationAwareinterface andFullTextFunctioninstances will store their ownQueryBuilderwhich will be serialized.I wasn't sure which type of tests to add since most of it is a refactor on how we do the
FullTextFunction-> query builder translation.