Skip to content

Commit

Permalink
Add ES|QL match operator (:) (elastic#114831)
Browse files Browse the repository at this point in the history
(cherry picked from commit f88f68d)
  • Loading branch information
carlosdelest committed Nov 6, 2024
1 parent a58d437 commit c1cb6da
Show file tree
Hide file tree
Showing 29 changed files with 2,595 additions and 2,249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.elasticsearch.xpack.esql.core.expression.Expression;
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MatchQueryPredicate;
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MultiMatchQueryPredicate;
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.StringQueryPredicate;
import org.elasticsearch.xpack.esql.core.expression.predicate.logical.And;
Expand All @@ -24,7 +23,6 @@
import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardLike;
import org.elasticsearch.xpack.esql.core.querydsl.query.BoolQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.ExistsQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.MatchQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.MultiMatchQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.NotQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
Expand Down Expand Up @@ -87,18 +85,6 @@ public static Query doTranslate(StringQueryPredicate q, TranslatorHandler handle
}
}

public static class Matches extends ExpressionTranslator<MatchQueryPredicate> {

@Override
protected Query asQuery(MatchQueryPredicate q, TranslatorHandler handler) {
return doTranslate(q, handler);
}

public static Query doTranslate(MatchQueryPredicate q, TranslatorHandler handler) {
return new MatchQuery(q.source(), handler.nameOf(q.field()), q.query(), q);
}
}

public static class MultiMatches extends ExpressionTranslator<MultiMatchQueryPredicate> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MatchQueryPredicate;
import org.elasticsearch.xpack.esql.core.tree.Source;

import java.util.Collections;
Expand All @@ -34,6 +33,7 @@ public class MatchQuery extends Query {
entry("analyzer", MatchQueryBuilder::analyzer),
entry("auto_generate_synonyms_phrase_query", (qb, s) -> qb.autoGenerateSynonymsPhraseQuery(Booleans.parseBoolean(s))),
entry("fuzziness", (qb, s) -> qb.fuzziness(Fuzziness.fromString(s))),
entry("boost", (qb, s) -> qb.boost(Float.parseFloat(s))),
entry("fuzzy_transpositions", (qb, s) -> qb.fuzzyTranspositions(Booleans.parseBoolean(s))),
entry("fuzzy_rewrite", MatchQueryBuilder::fuzzyRewrite),
entry("lenient", (qb, s) -> qb.lenient(Booleans.parseBoolean(s))),
Expand All @@ -46,19 +46,31 @@ public class MatchQuery extends Query {

private final String name;
private final Object text;
private final MatchQueryPredicate predicate;
private final Double boost;
private final Fuzziness fuzziness;
private final Map<String, String> options;

public MatchQuery(Source source, String name, Object text) {
this(source, name, text, null);
this(source, name, text, Map.of());
}

public MatchQuery(Source source, String name, Object text, MatchQueryPredicate predicate) {
public MatchQuery(Source source, String name, Object text, Map<String, String> options) {
super(source);
assert options != null;
this.name = name;
this.text = text;
this.predicate = predicate;
this.options = predicate == null ? Collections.emptyMap() : predicate.optionMap();
this.options = options;
this.boost = null;
this.fuzziness = null;
}

public MatchQuery(Source source, String name, Object text, Double boost, Fuzziness fuzziness) {
super(source);
this.name = name;
this.text = text;
this.options = Collections.emptyMap();
this.boost = boost;
this.fuzziness = fuzziness;
}

@Override
Expand All @@ -71,6 +83,12 @@ public QueryBuilder asBuilder() {
throw new IllegalArgumentException("illegal match option [" + k + "]");
}
});
if (boost != null) {
queryBuilder.boost(boost.floatValue());
}
if (fuzziness != null) {
queryBuilder.fuzziness(fuzziness);
}
return queryBuilder;
}

Expand All @@ -82,13 +100,9 @@ public Object text() {
return text;
}

MatchQueryPredicate predicate() {
return predicate;
}

@Override
public int hashCode() {
return Objects.hash(text, name, predicate);
return Objects.hash(text, name, options, boost, fuzziness);
}

@Override
Expand All @@ -98,11 +112,27 @@ public boolean equals(Object obj) {
}

MatchQuery other = (MatchQuery) obj;
return Objects.equals(text, other.text) && Objects.equals(name, other.name) && Objects.equals(predicate, other.predicate);
return Objects.equals(text, other.text)
&& Objects.equals(name, other.name)
&& Objects.equals(options, other.options)
&& Objects.equals(boost, other.boost)
&& Objects.equals(fuzziness, other.fuzziness);
}

@Override
protected String innerToString() {
return name + ":" + text;
}

public Double boost() {
return boost;
}

public Fuzziness fuzziness() {
return fuzziness;
}

public Map<String, String> options() {
return options;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public void testEqualsAndHashCode() {
}

private static MatchQuery copy(MatchQuery query) {
return new MatchQuery(query.source(), query.name(), query.text(), query.predicate());
return new MatchQuery(query.source(), query.name(), query.text(), query.options());
}

private static MatchQuery mutate(MatchQuery query) {
List<Function<MatchQuery, MatchQuery>> options = Arrays.asList(
q -> new MatchQuery(SourceTests.mutate(q.source()), q.name(), q.text(), q.predicate()),
q -> new MatchQuery(q.source(), randomValueOtherThan(q.name(), () -> randomAlphaOfLength(5)), q.text(), q.predicate()),
q -> new MatchQuery(q.source(), q.name(), randomValueOtherThan(q.text(), () -> randomAlphaOfLength(5)), q.predicate())
q -> new MatchQuery(SourceTests.mutate(q.source()), q.name(), q.text(), q.options()),
q -> new MatchQuery(q.source(), randomValueOtherThan(q.name(), () -> randomAlphaOfLength(5)), q.text(), q.options()),
q -> new MatchQuery(q.source(), q.name(), randomValueOtherThan(q.text(), () -> randomAlphaOfLength(5)), q.options())
);
// TODO mutate the predicate
return randomFrom(options).apply(query);
Expand All @@ -69,15 +69,15 @@ private static MatchQueryBuilder getBuilder(String options) {
final Source source = new Source(1, 1, StringUtils.EMPTY);
FieldAttribute fa = new FieldAttribute(EMPTY, "a", new EsField("af", KEYWORD, emptyMap(), true));
final MatchQueryPredicate mmqp = new MatchQueryPredicate(source, fa, "eggplant", options);
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp);
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp.optionMap());
return (MatchQueryBuilder) mmq.asBuilder();
}

public void testToString() {
final Source source = new Source(1, 1, StringUtils.EMPTY);
FieldAttribute fa = new FieldAttribute(EMPTY, "a", new EsField("af", KEYWORD, emptyMap(), true));
final MatchQueryPredicate mmqp = new MatchQueryPredicate(source, fa, "eggplant", "");
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp);
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp.optionMap());
assertEquals("MatchQuery@1:2[eggplant:foo]", mmq.toString());
}
}
Loading

0 comments on commit c1cb6da

Please sign in to comment.