Skip to content

Commit 782e2c6

Browse files
authored
[Rest Api Compatibility] CommonTermsQuery and cutoff_frequency param (#75896)
Previously removed in #42654. The query and the parameter won't work under rest api compatibility and an exception with a message is returned advising that just use of match/multi_match is enough relates #51816
1 parent 10fe3af commit 782e2c6

File tree

8 files changed

+210
-15
lines changed

8 files changed

+210
-15
lines changed

modules/analysis-common/build.gradle

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,11 @@ def v7compatibilityNotSupportedTests = {
3030
//marked as not needing compatible api
3131
'indices.analyze/10_analyze/htmlStrip_deprecated', // Cleanup versioned deprecations in analysis #41560
3232
'analysis-common/40_token_filters/delimited_payload_filter_error', //Remove preconfigured delimited_payload_filter #43686
33-
'analysis-common/20_analyzers/standard_html_strip' // Cleanup versioned deprecations in analysis #41560
33+
'analysis-common/20_analyzers/standard_html_strip', // Cleanup versioned deprecations in analysis #41560
34+
'search.query/50_queries_with_synonyms/Test common terms query with stacked tokens', // #42654 - `common` query throws an exception
3435
]
3536
}
3637

3738
tasks.named("yamlRestCompatTest").configure {
38-
systemProperty 'tests.rest.blacklist', ([
39-
'search.query/50_queries_with_synonyms/Test common terms query with stacked tokens', // #42654 - not sure, remove `common` query
40-
]+ v7compatibilityNotSupportedTests())
41-
.join(',')
39+
systemProperty 'tests.rest.blacklist', v7compatibilityNotSupportedTests().join(',')
4240
}

rest-api-spec/build.gradle

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ def v7compatibilityNotSupportedTests = {
8484

8585
'search/340_type_query/type query', //#47207 type query throws exception in compatible mode
8686
'search.aggregation/200_top_hits_metric/top_hits aggregation with sequence numbers', // #42809 the use nested path and filter sort throws an exception
87+
'search/310_match_bool_prefix/multi_match multiple fields with cutoff_frequency throws exception', //#42654 cutoff_frequency, common terms are not supported. Throwing an exception
88+
8789

8890
]
8991
}
@@ -92,11 +94,7 @@ tasks.named("yamlRestCompatTest").configure {
9294
// Skip these tests on Windows since the blacklist exceeds Windows CLI limits
9395
OS.current() != OS.WINDOWS
9496
}
95-
systemProperty 'tests.rest.blacklist', ([
96-
'search/310_match_bool_prefix/multi_match multiple fields with cutoff_frequency throws exception', //cutoff_frequency
97-
] + v7compatibilityNotSupportedTests())
98-
.join(',')
99-
97+
systemProperty 'tests.rest.blacklist', v7compatibilityNotSupportedTests().join(',')
10098
}
10199

102100
tasks.named("transformV7RestTests").configure({ task ->
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
setup:
3+
- skip:
4+
version: "9.0.0 - "
5+
reason: "compatible from 8.x to 7.x"
6+
features:
7+
- "headers"
8+
- "allowed_warnings_regex"
9+
- do:
10+
indices.create:
11+
index: "test"
12+
body:
13+
mappings:
14+
properties:
15+
my_field1:
16+
type: "text"
17+
my_field2:
18+
type: "text"
19+
headers:
20+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
21+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
22+
allowed_warnings_regex:
23+
- "\\[types removal\\].*"
24+
- do:
25+
index:
26+
index: "test"
27+
id: 1
28+
body:
29+
my_field1: "brown fox jump"
30+
my_field2: "xylophone"
31+
headers:
32+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
33+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
34+
allowed_warnings_regex:
35+
- "\\[types removal\\].*"
36+
- do:
37+
indices.refresh: {}
38+
headers:
39+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
40+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
41+
allowed_warnings_regex:
42+
- "\\[types removal\\].*"
43+
44+
---
45+
multi_match multiple fields with cutoff_frequency throws exception:
46+
- do:
47+
catch: "/cutoff_freqency is not supported. The \\[multi_match\\] query can skip block of documents efficiently if the total number of hits is not tracked/"
48+
search:
49+
rest_total_hits_as_int: true
50+
index: "test"
51+
body:
52+
query:
53+
multi_match:
54+
query: "brown"
55+
type: "bool_prefix"
56+
fields:
57+
- "my_field1"
58+
- "my_field2"
59+
cutoff_frequency: 0.001
60+
headers:
61+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
62+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
63+
allowed_warnings_regex:
64+
- "\\[types removal\\].*"
65+
66+
---
67+
match with cutoff_frequency throws exception:
68+
- do:
69+
catch: "/cutoff_freqency is not supported. The \\[match\\] query can skip block of documents efficiently if the total number of hits is not tracked/"
70+
search:
71+
rest_total_hits_as_int: true
72+
index: "test"
73+
body:
74+
query:
75+
match:
76+
my_field1:
77+
query: "brown"
78+
type: "bool_prefix"
79+
cutoff_frequency: 0.001
80+
headers:
81+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
82+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
83+
allowed_warnings_regex:
84+
- "\\[types removal\\].*"
85+
86+
---
87+
common querythrows exception:
88+
- do:
89+
catch: "/Common Terms Query usage is not supported. Use \\[match\\] query which can efficiently skip blocks of documents if the total number of hits is not tracked./"
90+
search:
91+
rest_total_hits_as_int: true
92+
index: "test"
93+
body:
94+
query:
95+
common:
96+
my_field1:
97+
query: "brown"
98+
type: "bool_prefix"
99+
cutoff_frequency: 0.001
100+
low_freq_operator: or
101+
headers:
102+
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
103+
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
104+
allowed_warnings_regex:
105+
- "\\[types removal\\].*"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.index.query;
10+
11+
import org.apache.lucene.search.Query;
12+
import org.elasticsearch.common.ParsingException;
13+
import org.elasticsearch.common.io.stream.StreamOutput;
14+
import org.elasticsearch.common.logging.DeprecationLogger;
15+
import org.elasticsearch.common.xcontent.ParseField;
16+
import org.elasticsearch.common.xcontent.XContentBuilder;
17+
import org.elasticsearch.common.xcontent.XContentParser;
18+
import org.elasticsearch.core.RestApiVersion;
19+
20+
import java.io.IOException;
21+
22+
public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQueryBuilder> {
23+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(CommonTermsQueryBuilder.class);
24+
public static final String COMMON_TERMS_QUERY_DEPRECATION_MSG = "Common Terms Query usage is not supported. " +
25+
"Use [match] query which can efficiently skip blocks of documents if the total number of hits is not tracked.";
26+
27+
public static ParseField NAME_V7 = new ParseField("common")
28+
.withAllDeprecated(COMMON_TERMS_QUERY_DEPRECATION_MSG)
29+
.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7));
30+
31+
@Override
32+
protected void doWriteTo(StreamOutput out) throws IOException {
33+
throw new UnsupportedOperationException("common_term_query is not meant to be serialized.");
34+
}
35+
36+
@Override
37+
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
38+
}
39+
40+
@Override
41+
protected Query doToQuery(SearchExecutionContext context) throws IOException {
42+
return null;
43+
}
44+
45+
@Override
46+
protected boolean doEquals(CommonTermsQueryBuilder other) {
47+
return false;
48+
}
49+
50+
@Override
51+
protected int doHashCode() {
52+
return 0;
53+
}
54+
55+
@Override
56+
public String getWriteableName() {
57+
return null;
58+
}
59+
60+
public static CommonTermsQueryBuilder fromXContent(XContentParser parser) throws IOException {
61+
deprecationLogger.compatibleApiWarning("common_term_query", COMMON_TERMS_QUERY_DEPRECATION_MSG);
62+
throw new ParsingException(parser.getTokenLocation(), COMMON_TERMS_QUERY_DEPRECATION_MSG);
63+
}
64+
65+
}

server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
2121
import org.elasticsearch.common.xcontent.XContentBuilder;
2222
import org.elasticsearch.common.xcontent.XContentParser;
23+
import org.elasticsearch.core.RestApiVersion;
2324
import org.elasticsearch.index.query.support.QueryParsers;
2425
import org.elasticsearch.index.search.MatchQueryParser;
2526

@@ -31,7 +32,12 @@
3132
* result of the analysis.
3233
*/
3334
public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
34-
35+
private static final String CUTOFF_FREQUENCY_DEPRECATION_MSG = "cutoff_freqency is not supported. " +
36+
"The [match] query can skip block of documents efficiently if the total number of hits is not tracked";
37+
public static final ParseField CUTOFF_FREQUENCY_FIELD =
38+
new ParseField("cutoff_frequency")
39+
.withAllDeprecated(CUTOFF_FREQUENCY_DEPRECATION_MSG)
40+
.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7));
3541
public static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
3642
public static final ParseField LENIENT_FIELD = new ParseField("lenient");
3743
public static final ParseField FUZZY_TRANSPOSITIONS_FIELD = new ParseField("fuzzy_transpositions");
@@ -464,6 +470,9 @@ public static MatchQueryBuilder fromXContent(XContentParser parser) throws IOExc
464470
queryName = parser.text();
465471
} else if (GENERATE_SYNONYMS_PHRASE_QUERY.match(currentFieldName, parser.getDeprecationHandler())) {
466472
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
473+
} else if (parser.getRestApiVersion() == RestApiVersion.V_7 &&
474+
CUTOFF_FREQUENCY_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
475+
throw new ParsingException(parser.getTokenLocation(), CUTOFF_FREQUENCY_DEPRECATION_MSG);
467476
} else {
468477
throw new ParsingException(parser.getTokenLocation(),
469478
"[" + NAME + "] query does not support [" + currentFieldName + "]");

server/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
2424
import org.elasticsearch.common.xcontent.XContentBuilder;
2525
import org.elasticsearch.common.xcontent.XContentParser;
26+
import org.elasticsearch.core.RestApiVersion;
2627
import org.elasticsearch.index.query.support.QueryParsers;
2728
import org.elasticsearch.index.search.MatchQueryParser;
2829
import org.elasticsearch.index.search.MultiMatchQueryParser;
@@ -42,7 +43,12 @@
4243
public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQueryBuilder> {
4344

4445
public static final String NAME = "multi_match";
45-
46+
private static final String CUTOFF_FREQUENCY_DEPRECATION_MSG = "cutoff_freqency is not supported." +
47+
" The [multi_match] query can skip block of documents efficiently if the total number of hits is not tracked";
48+
private static final ParseField CUTOFF_FREQUENCY_FIELD =
49+
new ParseField("cutoff_frequency")
50+
.withAllDeprecated(CUTOFF_FREQUENCY_DEPRECATION_MSG)
51+
.forRestApiVersion(RestApiVersion.equalTo(RestApiVersion.V_7));
4652
public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
4753
public static final Operator DEFAULT_OPERATOR = Operator.OR;
4854
public static final int DEFAULT_PHRASE_SLOP = MatchQueryParser.DEFAULT_PHRASE_SLOP;
@@ -570,7 +576,6 @@ public static MultiMatchQueryBuilder fromXContent(XContentParser parser) throws
570576
ZeroTermsQueryOption zeroTermsQuery = DEFAULT_ZERO_TERMS_QUERY;
571577
boolean autoGenerateSynonymsPhraseQuery = true;
572578
boolean fuzzyTranspositions = DEFAULT_FUZZY_TRANSPOSITIONS;
573-
574579
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
575580
String queryName = null;
576581

@@ -633,6 +638,9 @@ public static MultiMatchQueryBuilder fromXContent(XContentParser parser) throws
633638
autoGenerateSynonymsPhraseQuery = parser.booleanValue();
634639
} else if (FUZZY_TRANSPOSITIONS_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
635640
fuzzyTranspositions = parser.booleanValue();
641+
} else if (parser.getRestApiVersion() == RestApiVersion.V_7 &&
642+
CUTOFF_FREQUENCY_FIELD.match(currentFieldName, parser.getDeprecationHandler())) {
643+
throw new ParsingException(parser.getTokenLocation(), CUTOFF_FREQUENCY_DEPRECATION_MSG);
636644
} else {
637645
throw new ParsingException(parser.getTokenLocation(),
638646
"[" + NAME + "] query does not support [" + currentFieldName + "]");

server/src/main/java/org/elasticsearch/search/SearchModule.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.index.query.BoolQueryBuilder;
2828
import org.elasticsearch.index.query.BoostingQueryBuilder;
2929
import org.elasticsearch.index.query.CombinedFieldsQueryBuilder;
30+
import org.elasticsearch.index.query.CommonTermsQueryBuilder;
3031
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
3132
import org.elasticsearch.index.query.DisMaxQueryBuilder;
3233
import org.elasticsearch.index.query.DistanceFeatureQueryBuilder;
@@ -482,6 +483,12 @@ private ValuesSourceRegistry registerAggregations(List<SearchPlugin> plugins) {
482483
.setAggregatorRegistrar(CompositeAggregationBuilder::registerAggregators),
483484
builder
484485
);
486+
487+
if(RestApiVersion.minimumSupported() == RestApiVersion.V_7) {
488+
registerQuery(new QuerySpec<>(CommonTermsQueryBuilder.NAME_V7,
489+
(streamInput) -> new CommonTermsQueryBuilder(), CommonTermsQueryBuilder::fromXContent));
490+
}
491+
485492
registerFromPlugin(plugins, SearchPlugin::getAggregations, (agg) -> this.registerAggregation(agg, builder));
486493

487494
// after aggs have been registered, see if there are any new VSTypes that need to be linked to core fields

server/src/test/java/org/elasticsearch/search/SearchModuleTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.common.xcontent.XContentParser;
2222
import org.elasticsearch.core.RestApiVersion;
2323
import org.elasticsearch.index.query.AbstractQueryBuilder;
24+
import org.elasticsearch.index.query.CommonTermsQueryBuilder;
2425
import org.elasticsearch.index.query.QueryBuilder;
2526
import org.elasticsearch.index.query.QueryRewriteContext;
2627
import org.elasticsearch.index.query.SearchExecutionContext;
@@ -393,7 +394,10 @@ public CheckedBiConsumer<ShardSearchRequest, StreamOutput, IOException> getReque
393394

394395
//add here deprecated queries to make sure we log a deprecation warnings when they are used
395396
private static final String[] DEPRECATED_QUERIES = new String[] {"field_masking_span", "geo_polygon"};
396-
private static final String[] REST_COMPATIBLE_QUERIES = new String[] {TypeQueryV7Builder.NAME_V7.getPreferredName()};
397+
private static final String[] REST_COMPATIBLE_QUERIES = new String[] {
398+
TypeQueryV7Builder.NAME_V7.getPreferredName(),
399+
CommonTermsQueryBuilder.NAME_V7.getPreferredName()
400+
};
397401

398402
/**
399403
* Dummy test {@link AggregationBuilder} used to test registering aggregation builders.
@@ -674,7 +678,8 @@ public List<SearchPlugin.QuerySpec<?>> getQueries() {
674678
.filter(e -> RestApiVersion.minimumSupported().matches(e.restApiCompatibility))
675679
.filter(e -> RestApiVersion.current().matches(e.restApiCompatibility))
676680
.collect(toSet()),
677-
hasSize(searchModule.getNamedXContents().size()- REST_COMPATIBLE_QUERIES.length - 1 ));
681+
// -1 because of the registered in the test
682+
hasSize(searchModule.getNamedXContents().size() - REST_COMPATIBLE_QUERIES.length -1 ));
678683

679684

680685
final List<NamedXContentRegistry.Entry> compatEntry = searchModule.getNamedXContents().stream()

0 commit comments

Comments
 (0)