Skip to content

Commit 3b721c0

Browse files
kderussocarlosdelestelasticsearchmachineafoucret
committed
Take match_phrase out of snapshot and make tech preview (elastic#128925)
* Take match_phrase out of snapshot and make tech preview * Update docs/changelog/128925.yaml * PR feedback * Adding regenerated test data * Update docs/changelog/128925.yaml Co-authored-by: Carlos Delgado <[email protected]> * [CI] Auto commit changes from spotless * Checkstyle * Correct docs * Hopefully fix docs build * Found one more bad docs link - here's hoping this now fixes the doc build * OMG bitten by - vs _ --------- Co-authored-by: Carlos Delgado <[email protected]> Co-authored-by: elasticsearchmachine <[email protected]> Co-authored-by: Aurélien FOUCRET <[email protected]>
1 parent 5ec2c80 commit 3b721c0

File tree

10 files changed

+33
-60
lines changed

10 files changed

+33
-60
lines changed

docs/changelog/128925.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 128925
2+
summary: ES|QL - Add `match_phrase` full text function (tech preview)
3+
area: ES|QL
4+
type: enhancement
5+
issues: []

docs/reference/query-languages/esql/_snippets/functions/parameters/match_phrase.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
: Value to find in the provided field.
1010

1111
`options`
12-
: (Optional) MatchPhrase additional options as [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params). See [match_phrase query](/reference/query-languages/query-dsl/query-dsl-match-query.md#query-dsl-match-query-phrase) for more information.
12+
: (Optional) MatchPhrase additional options as [function named parameters](/reference/query-languages/esql/esql-syntax.md#esql-function-named-params). See [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for more information.
1313

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
import org.elasticsearch.common.settings.Settings;
1414
import org.elasticsearch.xpack.esql.VerificationException;
1515
import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase;
16-
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
17-
import org.elasticsearch.xpack.esql.action.EsqlQueryRequest;
18-
import org.elasticsearch.xpack.esql.action.EsqlQueryResponse;
1916
import org.hamcrest.Matchers;
2017
import org.junit.Before;
2118

@@ -34,12 +31,6 @@ public void setupIndex() {
3431
createAndPopulateIndex();
3532
}
3633

37-
@Override
38-
protected EsqlQueryResponse run(EsqlQueryRequest request) {
39-
assumeTrue("match_phrase function capability not available", EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled());
40-
return super.run(request);
41-
}
42-
4334
public void testSimpleWhereMatchPhrase() {
4435
var query = """
4536
FROM test

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,10 @@ public static List<Object[]> params() {
4949
params.add(new Object[] { "content:\"fox\"" });
5050
params.add(new Object[] { "qstr(\"content: fox\")" });
5151
params.add(new Object[] { "kql(\"content*: fox\")" });
52+
params.add(new Object[] { "match_phrase(content, \"fox\")" });
5253
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
5354
params.add(new Object[] { "term(content, \"fox\")" });
5455
}
55-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
56-
params.add(new Object[] { "match_phrase(content, \"fox\")" });
57-
}
5856
return params;
5957
}
6058

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ public enum Cap {
930930
/**
931931
* MATCH PHRASE function
932932
*/
933-
MATCH_PHRASE_FUNCTION(Build.current().isSnapshot());
933+
MATCH_PHRASE_FUNCTION;
934934

935935
private final boolean enabled;
936936

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,12 @@ public static List<NamedWriteableRegistry.Entry> getNamedWriteables() {
2424
entries.add(QueryString.ENTRY);
2525
entries.add(Match.ENTRY);
2626
entries.add(Kql.ENTRY);
27+
entries.add(MatchPhrase.ENTRY);
2728

2829
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
2930
entries.add(Term.ENTRY);
3031
}
3132

32-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
33-
entries.add(MatchPhrase.ENTRY);
34-
}
35-
3633
return Collections.unmodifiableList(entries);
3734
}
3835
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ public class MatchPhrase extends FullTextFunction implements OptionalArgument, P
9494
returnType = "boolean",
9595
preview = true,
9696
description = """
97-
Use `MATCH_PHRASE` to perform a <<query-dsl-match-query-phrase,match_phrase query>> on the specified field.
97+
Use `MATCH_PHRASE` to perform a [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) on the
98+
specified field.
9899
Using `MATCH_PHRASE` is equivalent to using the `match_phrase` query in the Elasticsearch Query DSL.
99100
100101
MatchPhrase can be used on <<text, text>> fields, as well as other field types like keyword, boolean, or date types.
@@ -149,7 +150,7 @@ public MatchPhrase(
149150
description = "Floating point number used to decrease or increase the relevance scores of the query. Defaults to 1.0."
150151
) },
151152
description = "(Optional) MatchPhrase additional options as <<esql-function-named-params,function named parameters>>."
152-
+ " See <<query-dsl-match-query-phrase,match_phrase query>> for more information.",
153+
+ " See [`match_phrase`](/reference/query-languages/query-dsl/query-dsl-match-query-phrase.md) for more information.",
153154
optional = true
154155
) Expression options
155156
) {

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

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,14 +1226,13 @@ public void testFieldBasedFullTextFunctions() throws Exception {
12261226
checkFieldBasedWithNonIndexedColumn(":", "text : \"cat\"", "operator");
12271227
checkFieldBasedFunctionNotAllowedAfterCommands(":", "operator", "title : \"Meditation\"");
12281228

1229+
checkFieldBasedWithNonIndexedColumn("MatchPhrase", "match_phrase(text, \"cat\")", "function");
1230+
checkFieldBasedFunctionNotAllowedAfterCommands("MatchPhrase", "function", "match_phrase(title, \"Meditation\")");
1231+
12291232
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
12301233
checkFieldBasedWithNonIndexedColumn("Term", "term(text, \"cat\")", "function");
12311234
checkFieldBasedFunctionNotAllowedAfterCommands("Term", "function", "term(title, \"Meditation\")");
12321235
}
1233-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
1234-
checkFieldBasedWithNonIndexedColumn("MatchPhrase", "match_phrase(text, \"cat\")", "function");
1235-
checkFieldBasedFunctionNotAllowedAfterCommands("MatchPhrase", "function", "match_phrase(title, \"Meditation\")");
1236-
}
12371236
}
12381237

12391238
private void checkFieldBasedFunctionNotAllowedAfterCommands(String functionName, String functionType, String functionInvocation) {
@@ -1357,12 +1356,10 @@ public void testFullTextFunctionsOnlyAllowedInWhere() throws Exception {
13571356
checkFullTextFunctionsOnlyAllowedInWhere(":", "title:\"Meditation\"", "operator");
13581357
checkFullTextFunctionsOnlyAllowedInWhere("QSTR", "qstr(\"Meditation\")", "function");
13591358
checkFullTextFunctionsOnlyAllowedInWhere("KQL", "kql(\"Meditation\")", "function");
1359+
checkFullTextFunctionsOnlyAllowedInWhere("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
13601360
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
13611361
checkFullTextFunctionsOnlyAllowedInWhere("Term", "term(title, \"Meditation\")", "function");
13621362
}
1363-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
1364-
checkFullTextFunctionsOnlyAllowedInWhere("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
1365-
}
13661363
}
13671364

13681365
private void checkFullTextFunctionsOnlyAllowedInWhere(String functionName, String functionInvocation, String functionType)
@@ -1392,12 +1389,13 @@ public void testFullTextFunctionsDisjunctions() {
13921389
checkWithFullTextFunctionsDisjunctions("title : \"Meditation\"");
13931390
checkWithFullTextFunctionsDisjunctions("qstr(\"title: Meditation\")");
13941391
checkWithFullTextFunctionsDisjunctions("kql(\"title: Meditation\")");
1392+
checkWithFullTextFunctionsDisjunctions("match_phrase(title, \"Meditation\")");
1393+
if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
1394+
checkWithFullTextFunctionsDisjunctions("multi_match(\"Meditation\", title, body)");
1395+
}
13951396
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
13961397
checkWithFullTextFunctionsDisjunctions("term(title, \"Meditation\")");
13971398
}
1398-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
1399-
checkWithFullTextFunctionsDisjunctions("match_phrase(title, \"Meditation\")");
1400-
}
14011399
}
14021400

14031401
private void checkWithFullTextFunctionsDisjunctions(String functionInvocation) {
@@ -1453,12 +1451,10 @@ public void testFullTextFunctionsWithNonBooleanFunctions() {
14531451
checkFullTextFunctionsWithNonBooleanFunctions(":", "title:\"Meditation\"", "operator");
14541452
checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"title: Meditation\")", "function");
14551453
checkFullTextFunctionsWithNonBooleanFunctions("KQL", "kql(\"title: Meditation\")", "function");
1454+
checkFullTextFunctionsWithNonBooleanFunctions("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
14561455
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
14571456
checkFullTextFunctionsWithNonBooleanFunctions("Term", "term(title, \"Meditation\")", "function");
14581457
}
1459-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
1460-
checkFullTextFunctionsWithNonBooleanFunctions("MatchPhrase", "match_phrase(title, \"Meditation\")", "function");
1461-
}
14621458
}
14631459

14641460
private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName, String functionInvocation, String functionType) {
@@ -1520,12 +1516,10 @@ private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName,
15201516
public void testFullTextFunctionsTargetsExistingField() throws Exception {
15211517
testFullTextFunctionTargetsExistingField("match(title, \"Meditation\")");
15221518
testFullTextFunctionTargetsExistingField("title : \"Meditation\"");
1519+
testFullTextFunctionTargetsExistingField("match_phrase(title, \"Meditation\")");
15231520
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
15241521
testFullTextFunctionTargetsExistingField("term(fist_name, \"Meditation\")");
15251522
}
1526-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
1527-
testFullTextFunctionTargetsExistingField("match_phrase(title, \"Meditation\")");
1528-
}
15291523
}
15301524

15311525
private void testFullTextFunctionTargetsExistingField(String functionInvocation) throws Exception {
@@ -2044,9 +2038,7 @@ public void testLookupJoinDataTypeMismatch() {
20442038
public void testFullTextFunctionOptions() {
20452039
checkOptionDataTypes(Match.ALLOWED_OPTIONS, "FROM test | WHERE match(title, \"Jean\", {\"%s\": %s})");
20462040
checkOptionDataTypes(QueryString.ALLOWED_OPTIONS, "FROM test | WHERE QSTR(\"title: Jean\", {\"%s\": %s})");
2047-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
2048-
checkOptionDataTypes(MatchPhrase.ALLOWED_OPTIONS, "FROM test | WHERE MATCH_PHRASE(title, \"Jean\", {\"%s\": %s})");
2049-
}
2041+
checkOptionDataTypes(MatchPhrase.ALLOWED_OPTIONS, "FROM test | WHERE MATCH_PHRASE(title, \"Jean\", {\"%s\": %s})");
20502042
}
20512043

20522044
/**
@@ -2101,12 +2093,10 @@ private static String exampleValueForType(DataType currentType) {
21012093
public void testFullTextFunctionCurrentlyUnsupportedBehaviour() throws Exception {
21022094
testFullTextFunctionsCurrentlyUnsupportedBehaviour("match(title, \"Meditation\")");
21032095
testFullTextFunctionsCurrentlyUnsupportedBehaviour("title : \"Meditation\"");
2096+
testFullTextFunctionsCurrentlyUnsupportedBehaviour("match_phrase(title, \"Meditation\")");
21042097
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
21052098
testFullTextFunctionsCurrentlyUnsupportedBehaviour("term(title, \"Meditation\")");
21062099
}
2107-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
2108-
testFullTextFunctionsCurrentlyUnsupportedBehaviour("match_phrase(title, \"Meditation\")");
2109-
}
21102100
}
21112101

21122102
private void testFullTextFunctionsCurrentlyUnsupportedBehaviour(String functionInvocation) throws Exception {
@@ -2121,14 +2111,16 @@ public void testFullTextFunctionsNullArgs() throws Exception {
21212111
checkFullTextFunctionNullArgs("match(title, null)", "second");
21222112
checkFullTextFunctionNullArgs("qstr(null)", "");
21232113
checkFullTextFunctionNullArgs("kql(null)", "");
2114+
checkFullTextFunctionNullArgs("match_phrase(null, \"query\")", "first");
2115+
checkFullTextFunctionNullArgs("match_phrase(title, null)", "second");
2116+
if (EsqlCapabilities.Cap.MULTI_MATCH_FUNCTION.isEnabled()) {
2117+
checkFullTextFunctionNullArgs("multi_match(null, title)", "first");
2118+
checkFullTextFunctionNullArgs("multi_match(\"query\", null)", "second");
2119+
}
21242120
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
21252121
checkFullTextFunctionNullArgs("term(null, \"query\")", "first");
21262122
checkFullTextFunctionNullArgs("term(title, null)", "second");
21272123
}
2128-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
2129-
checkFullTextFunctionNullArgs("match_phrase(null, \"query\")", "first");
2130-
checkFullTextFunctionNullArgs("match_phrase(title, null)", "second");
2131-
}
21322124
}
21332125

21342126
private void checkFullTextFunctionNullArgs(String functionInvocation, String argOrdinal) throws Exception {
@@ -2142,12 +2134,10 @@ public void testFullTextFunctionsConstantQuery() throws Exception {
21422134
checkFullTextFunctionsConstantQuery("match(title, category)", "second");
21432135
checkFullTextFunctionsConstantQuery("qstr(title)", "");
21442136
checkFullTextFunctionsConstantQuery("kql(title)", "");
2137+
checkFullTextFunctionsConstantQuery("match_phrase(title, tags)", "second");
21452138
if (EsqlCapabilities.Cap.TERM_FUNCTION.isEnabled()) {
21462139
checkFullTextFunctionsConstantQuery("term(title, tags)", "second");
21472140
}
2148-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
2149-
checkFullTextFunctionsConstantQuery("match_phrase(title, tags)", "second");
2150-
}
21512141
}
21522142

21532143
private void checkFullTextFunctionsConstantQuery(String functionInvocation, String argOrdinal) throws Exception {
@@ -2162,9 +2152,7 @@ public void testFullTextFunctionsInStats() {
21622152
checkFullTextFunctionsInStats("title : \"Meditation\"");
21632153
checkFullTextFunctionsInStats("qstr(\"title: Meditation\")");
21642154
checkFullTextFunctionsInStats("kql(\"title: Meditation\")");
2165-
if (EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled()) {
2166-
checkFullTextFunctionsInStats("match_phrase(title, \"Meditation\")");
2167-
}
2155+
checkFullTextFunctionsInStats("match_phrase(title, \"Meditation\")");
21682156
}
21692157

21702158
private void checkFullTextFunctionsInStats(String functionInvocation) {

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchPhraseTests.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
1212

1313
import org.elasticsearch.index.query.QueryBuilder;
14-
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
1514
import org.elasticsearch.xpack.esql.core.expression.Expression;
1615
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
1716
import org.elasticsearch.xpack.esql.core.expression.Literal;
@@ -23,7 +22,6 @@
2322
import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
2423
import org.elasticsearch.xpack.esql.io.stream.PlanStreamOutput;
2524
import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates;
26-
import org.junit.Before;
2725

2826
import java.util.ArrayList;
2927
import java.util.List;
@@ -41,11 +39,6 @@
4139
@FunctionName("match_phrase")
4240
public class MatchPhraseTests extends AbstractFunctionTestCase {
4341

44-
@Before
45-
public void checkCapability() {
46-
assumeTrue("MatchPhrase is not supported in this version of ESQL", EsqlCapabilities.Cap.MATCH_PHRASE_FUNCTION.isEnabled());
47-
}
48-
4942
public MatchPhraseTests(@Name("TestCase") Supplier<TestCaseSupplier.TestCase> testCaseSupplier) {
5043
this.testCase = testCaseSupplier.get();
5144
}

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ setup:
101101
- gt: {esql.functions.to_long: $functions_to_long}
102102
- match: {esql.functions.coalesce: $functions_coalesce}
103103
# Testing for the entire function set isn't feasible, so we just check that we return the correct count as an approximation.
104-
- length: {esql.functions: 145} # check the "sister" test below for a likely update to the same esql.functions length check
104+
- length: {esql.functions: 157} # check the "sister" test below for a likely update to the same esql.functions length check
105105

106106
---
107107
"Basic ESQL usage output (telemetry) non-snapshot version":

0 commit comments

Comments
 (0)