Skip to content

Commit 2251f80

Browse files
authored
Add ES|QL match operator (:) (#114831) (#116308)
(cherry picked from commit f88f68d)
1 parent f201df0 commit 2251f80

File tree

29 files changed

+2595
-2249
lines changed

29 files changed

+2595
-2249
lines changed

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/planner/ExpressionTranslators.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.elasticsearch.xpack.esql.core.expression.Expression;
1212
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
1313
import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
14-
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MatchQueryPredicate;
1514
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MultiMatchQueryPredicate;
1615
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.StringQueryPredicate;
1716
import org.elasticsearch.xpack.esql.core.expression.predicate.logical.And;
@@ -24,7 +23,6 @@
2423
import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardLike;
2524
import org.elasticsearch.xpack.esql.core.querydsl.query.BoolQuery;
2625
import org.elasticsearch.xpack.esql.core.querydsl.query.ExistsQuery;
27-
import org.elasticsearch.xpack.esql.core.querydsl.query.MatchQuery;
2826
import org.elasticsearch.xpack.esql.core.querydsl.query.MultiMatchQuery;
2927
import org.elasticsearch.xpack.esql.core.querydsl.query.NotQuery;
3028
import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
@@ -87,18 +85,6 @@ public static Query doTranslate(StringQueryPredicate q, TranslatorHandler handle
8785
}
8886
}
8987

90-
public static class Matches extends ExpressionTranslator<MatchQueryPredicate> {
91-
92-
@Override
93-
protected Query asQuery(MatchQueryPredicate q, TranslatorHandler handler) {
94-
return doTranslate(q, handler);
95-
}
96-
97-
public static Query doTranslate(MatchQueryPredicate q, TranslatorHandler handler) {
98-
return new MatchQuery(q.source(), handler.nameOf(q.field()), q.query(), q);
99-
}
100-
}
101-
10288
public static class MultiMatches extends ExpressionTranslator<MultiMatchQueryPredicate> {
10389

10490
@Override

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/query/MatchQuery.java

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import org.elasticsearch.index.query.Operator;
1313
import org.elasticsearch.index.query.QueryBuilder;
1414
import org.elasticsearch.index.query.QueryBuilders;
15-
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MatchQueryPredicate;
1615
import org.elasticsearch.xpack.esql.core.tree.Source;
1716

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

4747
private final String name;
4848
private final Object text;
49-
private final MatchQueryPredicate predicate;
49+
private final Double boost;
50+
private final Fuzziness fuzziness;
5051
private final Map<String, String> options;
5152

5253
public MatchQuery(Source source, String name, Object text) {
53-
this(source, name, text, null);
54+
this(source, name, text, Map.of());
5455
}
5556

56-
public MatchQuery(Source source, String name, Object text, MatchQueryPredicate predicate) {
57+
public MatchQuery(Source source, String name, Object text, Map<String, String> options) {
5758
super(source);
59+
assert options != null;
5860
this.name = name;
5961
this.text = text;
60-
this.predicate = predicate;
61-
this.options = predicate == null ? Collections.emptyMap() : predicate.optionMap();
62+
this.options = options;
63+
this.boost = null;
64+
this.fuzziness = null;
65+
}
66+
67+
public MatchQuery(Source source, String name, Object text, Double boost, Fuzziness fuzziness) {
68+
super(source);
69+
this.name = name;
70+
this.text = text;
71+
this.options = Collections.emptyMap();
72+
this.boost = boost;
73+
this.fuzziness = fuzziness;
6274
}
6375

6476
@Override
@@ -71,6 +83,12 @@ public QueryBuilder asBuilder() {
7183
throw new IllegalArgumentException("illegal match option [" + k + "]");
7284
}
7385
});
86+
if (boost != null) {
87+
queryBuilder.boost(boost.floatValue());
88+
}
89+
if (fuzziness != null) {
90+
queryBuilder.fuzziness(fuzziness);
91+
}
7492
return queryBuilder;
7593
}
7694

@@ -82,13 +100,9 @@ public Object text() {
82100
return text;
83101
}
84102

85-
MatchQueryPredicate predicate() {
86-
return predicate;
87-
}
88-
89103
@Override
90104
public int hashCode() {
91-
return Objects.hash(text, name, predicate);
105+
return Objects.hash(text, name, options, boost, fuzziness);
92106
}
93107

94108
@Override
@@ -98,11 +112,27 @@ public boolean equals(Object obj) {
98112
}
99113

100114
MatchQuery other = (MatchQuery) obj;
101-
return Objects.equals(text, other.text) && Objects.equals(name, other.name) && Objects.equals(predicate, other.predicate);
115+
return Objects.equals(text, other.text)
116+
&& Objects.equals(name, other.name)
117+
&& Objects.equals(options, other.options)
118+
&& Objects.equals(boost, other.boost)
119+
&& Objects.equals(fuzziness, other.fuzziness);
102120
}
103121

104122
@Override
105123
protected String innerToString() {
106124
return name + ":" + text;
107125
}
126+
127+
public Double boost() {
128+
return boost;
129+
}
130+
131+
public Fuzziness fuzziness() {
132+
return fuzziness;
133+
}
134+
135+
public Map<String, String> options() {
136+
return options;
137+
}
108138
}

x-pack/plugin/esql-core/src/test/java/org/elasticsearch/xpack/esql/core/querydsl/query/MatchQueryTests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ public void testEqualsAndHashCode() {
3737
}
3838

3939
private static MatchQuery copy(MatchQuery query) {
40-
return new MatchQuery(query.source(), query.name(), query.text(), query.predicate());
40+
return new MatchQuery(query.source(), query.name(), query.text(), query.options());
4141
}
4242

4343
private static MatchQuery mutate(MatchQuery query) {
4444
List<Function<MatchQuery, MatchQuery>> options = Arrays.asList(
45-
q -> new MatchQuery(SourceTests.mutate(q.source()), q.name(), q.text(), q.predicate()),
46-
q -> new MatchQuery(q.source(), randomValueOtherThan(q.name(), () -> randomAlphaOfLength(5)), q.text(), q.predicate()),
47-
q -> new MatchQuery(q.source(), q.name(), randomValueOtherThan(q.text(), () -> randomAlphaOfLength(5)), q.predicate())
45+
q -> new MatchQuery(SourceTests.mutate(q.source()), q.name(), q.text(), q.options()),
46+
q -> new MatchQuery(q.source(), randomValueOtherThan(q.name(), () -> randomAlphaOfLength(5)), q.text(), q.options()),
47+
q -> new MatchQuery(q.source(), q.name(), randomValueOtherThan(q.text(), () -> randomAlphaOfLength(5)), q.options())
4848
);
4949
// TODO mutate the predicate
5050
return randomFrom(options).apply(query);
@@ -69,15 +69,15 @@ private static MatchQueryBuilder getBuilder(String options) {
6969
final Source source = new Source(1, 1, StringUtils.EMPTY);
7070
FieldAttribute fa = new FieldAttribute(EMPTY, "a", new EsField("af", KEYWORD, emptyMap(), true));
7171
final MatchQueryPredicate mmqp = new MatchQueryPredicate(source, fa, "eggplant", options);
72-
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp);
72+
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp.optionMap());
7373
return (MatchQueryBuilder) mmq.asBuilder();
7474
}
7575

7676
public void testToString() {
7777
final Source source = new Source(1, 1, StringUtils.EMPTY);
7878
FieldAttribute fa = new FieldAttribute(EMPTY, "a", new EsField("af", KEYWORD, emptyMap(), true));
7979
final MatchQueryPredicate mmqp = new MatchQueryPredicate(source, fa, "eggplant", "");
80-
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp);
80+
final MatchQuery mmq = new MatchQuery(source, "eggplant", "foo", mmqp.optionMap());
8181
assertEquals("MatchQuery@1:2[eggplant:foo]", mmq.toString());
8282
}
8383
}

0 commit comments

Comments
 (0)