Skip to content

Commit fbbb7eb

Browse files
Fix type of fields
1 parent c308b1c commit fbbb7eb

File tree

7 files changed

+49
-27
lines changed

7 files changed

+49
-27
lines changed

x-pack/plugin/esql/qa/testFixtures/src/main/resources/multi-match-function.csv-spec

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ required_capability: multi_match_function
77

88
// tag::multi-match-with-field[]
99
FROM books
10-
| WHERE MULTI_MATCH("Faulkner", "author", "summary", {"fuzziness": 1})
10+
| WHERE MULTI_MATCH("Faulkner", author, summary, {"fuzziness": 1})
1111
| KEEP book_no, author
1212
| SORT book_no
1313
| LIMIT 5
@@ -28,7 +28,7 @@ testMultiMatchWithOptionsFuzziness
2828
required_capability: multi_match_function
2929

3030
from books
31-
| where multi_match("Pings", "title", "summary", {"fuzziness": 1})
31+
| where multi_match("Pings", title, summary, {"fuzziness": 1})
3232
| keep book_no;
3333
ignoreOrder:true
3434

@@ -44,7 +44,7 @@ required_capability: multi_match_function
4444

4545
// tag::multi-match-with-named-function-params[]
4646
FROM books
47-
| WHERE MULTI_MATCH("Hobbit Back Again", "title", "summary", {"operator": "AND"})
47+
| WHERE MULTI_MATCH("Hobbit Back Again", title, summary, {"operator": "AND"})
4848
| KEEP title;
4949
// end::multi-match-with-named-function-params[]
5050

@@ -58,7 +58,7 @@ testMultiMatchWithOptionsMinimumShouldMatch
5858
required_capability: multi_match_function
5959

6060
from books
61-
| where multi_match("Hobbit Back Again", "title", "summary", {"minimum_should_match": 2})
61+
| where multi_match("Hobbit Back Again", title, summary, {"minimum_should_match": 2})
6262
| keep title;
6363

6464
title:text
@@ -70,7 +70,7 @@ required_capability: multi_match_function
7070
required_capability: full_text_functions_disjunctions_compute_engine
7171

7272
from books
73-
| where multi_match("lord", "title", "summary", {"operator": "AND"}) or length(title) > 130
73+
| where multi_match("lord", title, summary, {"operator": "AND"}) or length(title) > 130
7474
| keep book_no
7575
;
7676
ignoreOrder: true

x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ required_capability: multi_match_function
119119
required_capability: metadata_score
120120

121121
from books metadata _score
122-
| where multi_match("Mark", "author", "title", {"fuzziness": 1})
122+
| where multi_match("Mark", author, title, {"fuzziness": 1})
123123
| keep book_no, title, author, _score;
124124
ignoreOrder:true
125125

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/ScoringIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
4646
public static List<Object[]> params() {
4747
List<Object[]> params = new ArrayList<>();
4848
params.add(new Object[] { "match(content, \"fox\")" });
49-
params.add(new Object[] { "multi_match(\"fox\", \"content\", {\"operator\": \"AND\"})" });
49+
params.add(new Object[] { "multi_match(\"fox\", content, {\"operator\": \"AND\"})" });
5050
params.add(new Object[] { "content:\"fox\"" });
5151
params.add(new Object[] { "qstr(\"content: fox\")" });
5252
params.add(new Object[] { "kql(\"content*: fox\")" });

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,16 +494,21 @@ public Object queryAsObject() {
494494
protected Query translate(TranslatorHandler handler) {
495495
var fieldAttribute = fieldAsFieldAttribute();
496496
Check.notNull(fieldAttribute, "Match must have a field attribute as the first argument");
497+
String fieldName = getNameFromFieldAttribute(fieldAttribute);
498+
// Make query lenient so mixed field types can be queried when a field type is incompatible with the value provided
499+
return new MatchQuery(source(), fieldName, queryAsObject(), matchQueryOptions());
500+
}
501+
502+
public static String getNameFromFieldAttribute(FieldAttribute fieldAttribute) {
497503
String fieldName = fieldAttribute.name();
498504
if (fieldAttribute.field() instanceof MultiTypeEsField multiTypeEsField) {
499505
// If we have multiple field types, we allow the query to be done, but getting the underlying field name
500506
fieldName = multiTypeEsField.getName();
501507
}
502-
// Make query lenient so mixed field types can be queried when a field type is incompatible with the value provided
503-
return new MatchQuery(source(), fieldName, queryAsObject(), matchQueryOptions());
508+
return fieldName;
504509
}
505510

506-
private FieldAttribute fieldAsFieldAttribute() {
511+
public static FieldAttribute fieldAsFieldAttribute(Expression field) {
507512
Expression fieldExpression = field;
508513
// Field may be converted to other data type (field_name :: data_type), so we need to check the original field
509514
if (fieldExpression instanceof AbstractConvertFunction convertFunction) {
@@ -512,6 +517,10 @@ private FieldAttribute fieldAsFieldAttribute() {
512517
return fieldExpression instanceof FieldAttribute fieldAttribute ? fieldAttribute : null;
513518
}
514519

520+
private FieldAttribute fieldAsFieldAttribute() {
521+
return fieldAsFieldAttribute(field);
522+
}
523+
515524
@Override
516525
public boolean equals(Object o) {
517526
// Match does not serialize options, as they get included in the query builder. We need to override equals and hashcode to

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MultiMatch.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.common.io.stream.StreamOutput;
1515
import org.elasticsearch.index.query.QueryBuilder;
1616
import org.elasticsearch.xpack.esql.capabilities.PostAnalysisPlanVerificationAware;
17+
import org.elasticsearch.xpack.esql.common.Failures;
1718
import org.elasticsearch.xpack.esql.core.InvalidArgumentException;
1819
import org.elasticsearch.xpack.esql.core.expression.EntryExpression;
1920
import org.elasticsearch.xpack.esql.core.expression.Expression;
@@ -24,13 +25,15 @@
2425
import org.elasticsearch.xpack.esql.core.tree.Source;
2526
import org.elasticsearch.xpack.esql.core.type.DataType;
2627
import org.elasticsearch.xpack.esql.core.type.DataTypeConverter;
28+
import org.elasticsearch.xpack.esql.core.util.Check;
2729
import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesTo;
2830
import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesToLifecycle;
2931
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
3032
import org.elasticsearch.xpack.esql.expression.function.MapParam;
3133
import org.elasticsearch.xpack.esql.expression.function.OptionalArgument;
3234
import org.elasticsearch.xpack.esql.expression.function.Param;
3335
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
36+
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
3437
import org.elasticsearch.xpack.esql.planner.TranslatorHandler;
3538
import org.elasticsearch.xpack.esql.querydsl.query.MultiMatchQuery;
3639

@@ -40,6 +43,7 @@
4043
import java.util.Map;
4144
import java.util.Objects;
4245
import java.util.Set;
46+
import java.util.function.BiConsumer;
4347
import java.util.stream.Stream;
4448

4549
import static java.util.Map.entry;
@@ -240,7 +244,10 @@ protected NodeInfo<? extends Expression> info() {
240244
protected Query translate(TranslatorHandler handler) {
241245
Map<String, Float> fieldsWithBoost = new HashMap<>();
242246
for (Expression field : fields) {
243-
fieldsWithBoost.put(unpackLiteralValue((Literal) field), 1.0f);
247+
var fieldAttribute = Match.fieldAsFieldAttribute(field);
248+
Check.notNull(fieldAttribute, "MultiMatch must have field attributes as arguments #2 to #N-1.");
249+
String fieldName = Match.getNameFromFieldAttribute(fieldAttribute);
250+
fieldsWithBoost.put(fieldName, 1.0f);
244251
}
245252
return new MultiMatchQuery(source(), Objects.toString(queryAsObject()), fieldsWithBoost, getOptions());
246253
}
@@ -369,4 +376,10 @@ public boolean equals(Object o) {
369376
public int hashCode() {
370377
return Objects.hash(fields(), query(), queryBuilder());
371378
}
379+
380+
@Override
381+
public BiConsumer<LogicalPlan, Failures> postAnalysisPlanVerification() {
382+
// TODO
383+
return super.postAnalysisPlanVerification();
384+
}
372385
}

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,17 +2329,17 @@ public void testQueryStringOptions() {
23292329

23302330
public void testMultiMatchOptions() {
23312331
// Check positive cases
2332-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"analyzer\": \"standard\"})");
2333-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"slop\": 10})");
2334-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"auto_generate_synonyms_phrase_query\": true})");
2335-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"fuzziness\": 2})");
2336-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"fuzzy_transpositions\": false})");
2337-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"lenient\": false})");
2338-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"max_expansions\": 10})");
2339-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"minimum_should_match\": \"2\"})");
2340-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"operator\": \"AND\"})");
2341-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"prefix_length\": 2})");
2342-
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"tie_breaker\": 1.0})");
2332+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"analyzer\": \"standard\"})");
2333+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", last_name, {\"slop\": 10})");
2334+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"auto_generate_synonyms_phrase_query\": true})");
2335+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"fuzziness\": 2})");
2336+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"fuzzy_transpositions\": false})");
2337+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"lenient\": false})");
2338+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"max_expansions\": 10})");
2339+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"minimum_should_match\": \"2\"})");
2340+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"operator\": \"AND\"})");
2341+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"prefix_length\": 2})");
2342+
query("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"tie_breaker\": 1.0})");
23432343
// TODO: "type" option?
23442344

23452345
// Check all data types for available options
@@ -2363,7 +2363,7 @@ public void testMultiMatchOptions() {
23632363
queryOptionValue = "\"" + optionValue + "\"";
23642364
}
23652365

2366-
String query = "FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\""
2366+
String query = "FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\""
23672367
+ optionName
23682368
+ "\": "
23692369
+ queryOptionValue
@@ -2378,7 +2378,7 @@ public void testMultiMatchOptions() {
23782378
assertEquals(
23792379
"1:19: Invalid option ["
23802380
+ optionName
2381-
+ "] in [MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\""
2381+
+ "] in [MULTI_MATCH(\"Jean\", first_name, last_name, {\""
23822382
+ optionName
23832383
+ "\": "
23842384
+ queryOptionValue
@@ -2398,9 +2398,9 @@ public void testMultiMatchOptions() {
23982398
}
23992399

24002400
assertThat(
2401-
error("FROM test | WHERE MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", {\"unknown_option\": true})"),
2401+
error("FROM test | WHERE MULTI_MATCH(\"Jean\", first_name, last_name, {\"unknown_option\": true})"),
24022402
containsString(
2403-
"1:19: Invalid option [unknown_option] in [MULTI_MATCH(\"Jean\", \"first_name\", \"last_name\", "
2403+
"1:19: Invalid option [unknown_option] in [MULTI_MATCH(\"Jean\", first_name, last_name, "
24042404
+ "{\"unknown_option\": true})], expected one of "
24052405
)
24062406
);

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1661,7 +1661,7 @@ public void testQStrOptionsPushDown() {
16611661
public void testMultiMatchOptionsPushDown() {
16621662
String query = """
16631663
from test
1664-
| where MULTI_MATCH("Anna", "first_name", "last_name", {"slop": 10, "analyzer": "auto",
1664+
| where MULTI_MATCH("Anna", first_name, last_name, {"slop": 10, "analyzer": "auto",
16651665
"auto_generate_synonyms_phrase_query": "false", "fuzziness": "auto", "fuzzy_transpositions": false, "lenient": "false",
16661666
"max_expansions": 10, "minimum_should_match": 3, "operator": "AND", "prefix_length": 20, "tie_breaker": 1.0})
16671667
""";

0 commit comments

Comments
 (0)