Browse Source

Deprecate CommonTermsQuery and cutoff_frequency (#42619)

* Deprecate CommonTermsQuery and cutoff_frequency

Since the max_score optimization landed in Elasticsearch 7,
the CommonTermsQuery is redundant and slower. Moreover the
cutoff_frequency parameter for MatchQuery and MultiMatchQuery
is redundant.

Relates to #27096
Marios Trivyzas 6 years ago
parent
commit
04b7449731
18 changed files with 145 additions and 51 deletions
  1. 7 0
      docs/reference/query-dsl/common-terms-query.asciidoc
  2. 3 0
      docs/reference/query-dsl/match-query.asciidoc
  3. 27 0
      modules/analysis-common/src/test/resources/rest-api-spec/test/search.query/50_queries_with_synonyms.yml
  4. 5 0
      server/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java
  5. 4 0
      server/src/main/java/org/apache/lucene/queries/ExtendedCommonTermsQuery.java
  6. 11 0
      server/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java
  7. 14 1
      server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
  8. 14 1
      server/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java
  9. 3 0
      server/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
  10. 4 0
      server/src/main/java/org/elasticsearch/index/search/MatchQuery.java
  11. 5 2
      server/src/main/java/org/elasticsearch/search/SearchModule.java
  12. 40 0
      server/src/test/java/org/elasticsearch/index/query/CommonTermsQueryBuilderTests.java
  13. 1 3
      server/src/test/java/org/elasticsearch/index/query/CommonTermsQueryParserTests.java
  14. 1 5
      server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java
  15. 0 3
      server/src/test/java/org/elasticsearch/index/query/MultiMatchQueryBuilderTests.java
  16. 3 3
      server/src/test/java/org/elasticsearch/search/SearchModuleTests.java
  17. 2 31
      server/src/test/java/org/elasticsearch/search/profile/query/RandomQueryGenerator.java
  18. 1 2
      test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java

+ 7 - 0
docs/reference/query-dsl/common-terms-query.asciidoc

@@ -1,6 +1,8 @@
 [[query-dsl-common-terms-query]]
 === Common Terms Query
 
+deprecated[7.3.0,"Use <<query-dsl-match-query>> instead, which skips blocks of documents efficiently, without any configuration, provided that the total number of hits is not tracked."]
+
 The `common` terms query is a modern alternative to stopwords which
 improves the precision and recall of search results (by taking stopwords
 into account), without sacrificing performance.
@@ -83,6 +85,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]]
 
 The number of terms which should match can be controlled with the
 <<query-dsl-minimum-should-match,`minimum_should_match`>>
@@ -108,6 +111,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]]
 
 which is roughly equivalent to:
 
@@ -154,6 +158,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]]
 
 which is roughly equivalent to:
 
@@ -209,6 +214,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]]
 
 which is roughly equivalent to:
 
@@ -270,6 +276,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]]
 
 which is roughly equivalent to:
 

+ 3 - 0
docs/reference/query-dsl/match-query.asciidoc

@@ -122,6 +122,8 @@ GET /_search
 [[query-dsl-match-query-cutoff]]
 ===== Cutoff frequency
 
+deprecated[7.3.0,"This option can be omitted as the <<query-dsl-match-query>> can skip block of documents efficiently, without any configuration, provided that the total number of hits is not tracked."]
+
 The match query supports a `cutoff_frequency` that allows
 specifying an absolute or relative document frequency where high
 frequency terms are moved into an optional subquery and are only scored
@@ -158,6 +160,7 @@ GET /_search
 }
 --------------------------------------------------
 // CONSOLE
+// TEST[warning:Deprecated field [cutoff_frequency] used, replaced by [you can omit this option, the [match] query can skip block of documents efficiently if the total number of hits is not tracked]]
 
 IMPORTANT: The `cutoff_frequency` option operates on a per-shard-level. This means
 that when trying it out on test indexes with low document numbers you

+ 27 - 0
modules/analysis-common/src/test/resources/rest-api-spec/test/search.query/50_queries_with_synonyms.yml

@@ -1,5 +1,8 @@
 ---
 "Test common terms query with stacked tokens":
+  - skip:
+      features: "warnings"
+
   - do:
       indices.create:
           index: test
@@ -47,6 +50,8 @@
           refresh: true
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -62,6 +67,8 @@
   - match: { hits.hits.2._id: "3" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -76,6 +83,8 @@
   - match: { hits.hits.1._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -90,6 +99,8 @@
   - match: { hits.hits.2._id: "3" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -103,6 +114,8 @@
   - match: { hits.hits.0._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -118,6 +131,8 @@
   - match: { hits.hits.1._id: "1" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -132,6 +147,8 @@
   - match: { hits.hits.0._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -144,6 +161,8 @@
   - match: { hits.hits.0._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [common] used, replaced by [[match] query which can efficiently skip blocks of documents if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -158,6 +177,8 @@
   - match: { hits.hits.2._id: "3" }
 
   - do:
+      warnings:
+        - 'Deprecated field [cutoff_frequency] used, replaced by [you can omit this option, the [match] query can skip block of documents efficiently if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -172,6 +193,8 @@
   - match: { hits.hits.1._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [cutoff_frequency] used, replaced by [you can omit this option, the [match] query can skip block of documents efficiently if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -187,6 +210,8 @@
   - match: { hits.hits.2._id: "3" }
 
   - do:
+      warnings:
+        - 'Deprecated field [cutoff_frequency] used, replaced by [you can omit this option, the [match] query can skip block of documents efficiently if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:
@@ -201,6 +226,8 @@
   - match: { hits.hits.1._id: "2" }
 
   - do:
+      warnings:
+        - 'Deprecated field [cutoff_frequency] used, replaced by [you can omit this option, the [multi_match] query can skip block of documents efficiently if the total number of hits is not tracked]'
       search:
         rest_total_hits_as_int: true
         body:

+ 5 - 0
server/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java

@@ -278,6 +278,11 @@ public abstract class BlendedTermQuery extends Query {
         return Objects.hash(classHash(), Arrays.hashCode(equalsTerms()));
     }
 
+    /**
+     * @deprecated Since max_score optimization landed in 7.0, normal MultiMatchQuery
+     *             will achieve the same result without any configuration.
+     */
+    @Deprecated
     public static BlendedTermQuery commonTermsBlendedQuery(Term[] terms, final float[] boosts, final float maxTermFrequency) {
         return new BlendedTermQuery(terms, boosts) {
             @Override

+ 4 - 0
server/src/main/java/org/apache/lucene/queries/ExtendedCommonTermsQuery.java

@@ -26,7 +26,11 @@ import org.elasticsearch.common.lucene.search.Queries;
  * Extended version of {@link CommonTermsQuery} that allows to pass in a
  * {@code minimumNumberShouldMatch} specification that uses the actual num of high frequent terms
  * to calculate the minimum matching terms.
+ *
+ * @deprecated Since max_optimization optimization landed in 7.0, normal MatchQuery
+ *             will achieve the same result without any configuration.
  */
+@Deprecated
 public class ExtendedCommonTermsQuery extends CommonTermsQuery {
 
     public ExtendedCommonTermsQuery(Occur highFreqOccur, Occur lowFreqOccur, float maxTermFrequency) {

+ 11 - 0
server/src/main/java/org/elasticsearch/index/query/CommonTermsQueryBuilder.java

@@ -47,9 +47,16 @@ import java.util.Objects;
  * and high-frequency terms are added to an optional boolean clause. The
  * optional clause is only executed if the required "low-frequency' clause
  * matches.
+ *
+ * @deprecated Since max_optimization optimization landed in 7.0, normal MatchQuery
+ *             will achieve the same result without any configuration.
  */
+@Deprecated
 public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQueryBuilder> {
 
+    public static final String COMMON_TERMS_QUERY_DEPRECATION_MSG = "[match] query which can efficiently " +
+        "skip blocks of documents if the total number of hits is not tracked";
+
     public static final String NAME = "common";
 
     public static final float DEFAULT_CUTOFF_FREQ = 0.01f;
@@ -85,7 +92,9 @@ public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQue
 
     /**
      * Constructs a new common terms query.
+     * @deprecated See {@link CommonTermsQueryBuilder} for more details.
      */
+    @Deprecated
     public CommonTermsQueryBuilder(String fieldName, Object text) {
         if (Strings.isEmpty(fieldName)) {
             throw new IllegalArgumentException("field name is null or empty");
@@ -99,7 +108,9 @@ public class CommonTermsQueryBuilder extends AbstractQueryBuilder<CommonTermsQue
 
     /**
      * Read from a stream.
+     * @deprecated See {@link CommonTermsQueryBuilder} for more details.
      */
+    @Deprecated
     public CommonTermsQueryBuilder(StreamInput in) throws IOException {
         super(in);
         fieldName = in.readString();

+ 14 - 1
server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java

@@ -42,8 +42,18 @@ import java.util.Objects;
  * result of the analysis.
  */
 public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
+
+    private static final String CUTOFF_FREQUENCY_DEPRECATION_MSG = "you can omit this option, " +
+        "the [match] query can skip block of documents efficiently if the total number of hits is not tracked";
+
     public static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
-    public static final ParseField CUTOFF_FREQUENCY_FIELD = new ParseField("cutoff_frequency");
+    /**
+     * @deprecated Since max_optimization optimization landed in 7.0, normal MatchQuery
+     *             will achieve the same result without any configuration.
+     */
+    @Deprecated
+    public static final ParseField CUTOFF_FREQUENCY_FIELD =
+        new ParseField("cutoff_frequency").withAllDeprecated(CUTOFF_FREQUENCY_DEPRECATION_MSG);
     public static final ParseField LENIENT_FIELD = new ParseField("lenient");
     public static final ParseField FUZZY_TRANSPOSITIONS_FIELD = new ParseField("fuzzy_transpositions");
     public static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
@@ -235,7 +245,10 @@ public class MatchQueryBuilder extends AbstractQueryBuilder<MatchQueryBuilder> {
      * Set a cutoff value in [0..1] (or absolute number &gt;=1) representing the
      * maximum threshold of a terms document frequency to be considered a low
      * frequency term.
+     *
+     * @deprecated see {@link MatchQueryBuilder#CUTOFF_FREQUENCY_FIELD} for more details
      */
+    @Deprecated
     public MatchQueryBuilder cutoffFrequency(float cutoff) {
         this.cutoffFrequency = cutoff;
         return this;

+ 14 - 1
server/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java

@@ -50,6 +50,10 @@ import java.util.TreeMap;
  * Same as {@link MatchQueryBuilder} but supports multiple fields.
  */
 public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQueryBuilder> {
+
+    private static final String CUTOFF_FREQUENCY_DEPRECATION_MSG = "you can omit this option, " +
+        "the [multi_match] query can skip block of documents efficiently if the total number of hits is not tracked";
+
     public static final String NAME = "multi_match";
 
     public static final MultiMatchQueryBuilder.Type DEFAULT_TYPE = MultiMatchQueryBuilder.Type.BEST_FIELDS;
@@ -63,7 +67,8 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
     private static final ParseField SLOP_FIELD = new ParseField("slop");
     private static final ParseField ZERO_TERMS_QUERY_FIELD = new ParseField("zero_terms_query");
     private static final ParseField LENIENT_FIELD = new ParseField("lenient");
-    private static final ParseField CUTOFF_FREQUENCY_FIELD = new ParseField("cutoff_frequency");
+    private static final ParseField CUTOFF_FREQUENCY_FIELD =
+        new ParseField("cutoff_frequency").withAllDeprecated(CUTOFF_FREQUENCY_DEPRECATION_MSG);
     private static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker");
     private static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
     private static final ParseField MINIMUM_SHOULD_MATCH_FIELD = new ParseField("minimum_should_match");
@@ -484,7 +489,11 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
      * Set a cutoff value in [0..1] (or absolute number &gt;=1) representing the
      * maximum threshold of a terms document frequency to be considered a low
      * frequency term.
+     *
+     * @deprecated Since max_score optimization landed in 7.0, normal MultiMatchQuery
+     *             will achieve the same result without any configuration.
      */
+    @Deprecated
     public MultiMatchQueryBuilder cutoffFrequency(float cutoff) {
         this.cutoffFrequency = cutoff;
         return this;
@@ -494,7 +503,11 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder<MultiMatchQuery
      * Set a cutoff value in [0..1] (or absolute number &gt;=1) representing the
      * maximum threshold of a terms document frequency to be considered a low
      * frequency term.
+     *
+     * @deprecated Since max_score optimization landed in 7.0, normal MultiMatchQuery
+     *             will achieve the same result without any configuration.
      */
+    @Deprecated
     public MultiMatchQueryBuilder cutoffFrequency(Float cutoff) {
         this.cutoffFrequency = cutoff;
         return this;

+ 3 - 0
server/src/main/java/org/elasticsearch/index/query/QueryBuilders.java

@@ -66,7 +66,10 @@ public final class QueryBuilders {
      *
      * @param fieldName The field name.
      * @param text The query text (to be analyzed).
+     *
+     * @deprecated See {@link CommonTermsQueryBuilder}
      */
+    @Deprecated
     public static CommonTermsQueryBuilder commonTermsQuery(String fieldName, Object text) {
         return new CommonTermsQueryBuilder(fieldName, text);
     }

+ 4 - 0
server/src/main/java/org/elasticsearch/index/search/MatchQuery.java

@@ -194,6 +194,10 @@ public class MatchQuery {
         this.occur = occur;
     }
 
+    /**
+     * @deprecated See {@link MatchQueryBuilder#setCommonTermsCutoff(Float)} for more details
+     */
+    @Deprecated
     public void setCommonTermsCutoff(Float cutoff) {
         this.commonTermsCutoff = cutoff;
     }

+ 5 - 2
server/src/main/java/org/elasticsearch/search/SearchModule.java

@@ -21,6 +21,7 @@ package org.elasticsearch.search;
 
 import org.apache.lucene.search.BooleanQuery;
 import org.elasticsearch.common.NamedRegistry;
+import org.elasticsearch.common.ParseField;
 import org.elasticsearch.common.geo.GeoShapeType;
 import org.elasticsearch.common.geo.ShapesAvailability;
 import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -32,7 +33,6 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry;
 import org.elasticsearch.common.xcontent.ParseFieldRegistry;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.MatchBoolPrefixQueryBuilder;
 import org.elasticsearch.index.query.BoostingQueryBuilder;
 import org.elasticsearch.index.query.CommonTermsQueryBuilder;
 import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
@@ -49,6 +49,7 @@ import org.elasticsearch.index.query.IdsQueryBuilder;
 import org.elasticsearch.index.query.IntervalQueryBuilder;
 import org.elasticsearch.index.query.IntervalsSourceProvider;
 import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.index.query.MatchBoolPrefixQueryBuilder;
 import org.elasticsearch.index.query.MatchNoneQueryBuilder;
 import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
 import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
@@ -271,6 +272,7 @@ import java.util.function.Function;
 
 import static java.util.Collections.unmodifiableMap;
 import static java.util.Objects.requireNonNull;
+import static org.elasticsearch.index.query.CommonTermsQueryBuilder.COMMON_TERMS_QUERY_DEPRECATION_MSG;
 import static org.elasticsearch.index.query.SpanNearQueryBuilder.SpanGapQueryBuilder;
 
 /**
@@ -767,7 +769,8 @@ public class SearchModule {
         registerQuery(new QuerySpec<>(MoreLikeThisQueryBuilder.NAME, MoreLikeThisQueryBuilder::new,
                 MoreLikeThisQueryBuilder::fromXContent));
         registerQuery(new QuerySpec<>(WrapperQueryBuilder.NAME, WrapperQueryBuilder::new, WrapperQueryBuilder::fromXContent));
-        registerQuery(new QuerySpec<>(CommonTermsQueryBuilder.NAME, CommonTermsQueryBuilder::new, CommonTermsQueryBuilder::fromXContent));
+        registerQuery(new QuerySpec<>(new ParseField(CommonTermsQueryBuilder.NAME).withAllDeprecated(COMMON_TERMS_QUERY_DEPRECATION_MSG),
+                CommonTermsQueryBuilder::new, CommonTermsQueryBuilder::fromXContent));
         registerQuery(
                 new QuerySpec<>(SpanMultiTermQueryBuilder.NAME, SpanMultiTermQueryBuilder::new, SpanMultiTermQueryBuilder::fromXContent));
         registerQuery(new QuerySpec<>(FunctionScoreQueryBuilder.NAME, FunctionScoreQueryBuilder::new,

+ 40 - 0
server/src/test/java/org/elasticsearch/index/query/CommonTermsQueryBuilderTests.java

@@ -111,6 +111,30 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
         assertThat(extendedCommonTermsQuery.getLowFreqMinimumNumberShouldMatchSpec(), equalTo(queryBuilder.lowFreqMinimumShouldMatch()));
     }
 
+    @Override
+    public void testUnknownField() throws IOException {
+        super.testUnknownField();
+        assertDeprecationWarning();
+    }
+
+    @Override
+    public void testUnknownObjectException() throws IOException {
+        super.testUnknownObjectException();
+        assertDeprecationWarning();
+    }
+
+    @Override
+    public void testFromXContent() throws IOException {
+        super.testFromXContent();
+        assertDeprecationWarning();
+    }
+
+    @Override
+    public void testValidOutput() throws IOException {
+        super.testValidOutput();
+        assertDeprecationWarning();
+    }
+
     public void testIllegalArguments() {
         IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new CommonTermsQueryBuilder(null, "text"));
         assertEquals("field name is null or empty", e.getMessage());
@@ -146,6 +170,8 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
         assertEquals(query, Operator.OR, queryBuilder.lowFreqOperator());
         assertEquals(query, Operator.AND, queryBuilder.highFreqOperator());
         assertEquals(query, "nelly the elephant not as a cartoon", queryBuilder.value());
+
+        assertDeprecationWarning();
     }
 
     public void testCommonTermsQuery1() throws IOException {
@@ -155,6 +181,8 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
         ExtendedCommonTermsQuery ectQuery = (ExtendedCommonTermsQuery) parsedQuery;
         assertThat(ectQuery.getHighFreqMinimumNumberShouldMatchSpec(), nullValue());
         assertThat(ectQuery.getLowFreqMinimumNumberShouldMatchSpec(), equalTo("2"));
+
+        assertDeprecationWarning();
     }
 
     public void testCommonTermsQuery2() throws IOException {
@@ -164,6 +192,8 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
         ExtendedCommonTermsQuery ectQuery = (ExtendedCommonTermsQuery) parsedQuery;
         assertThat(ectQuery.getHighFreqMinimumNumberShouldMatchSpec(), equalTo("50%"));
         assertThat(ectQuery.getLowFreqMinimumNumberShouldMatchSpec(), equalTo("5<20%"));
+
+        assertDeprecationWarning();
     }
 
     public void testCommonTermsQuery3() throws IOException {
@@ -173,12 +203,16 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
         ExtendedCommonTermsQuery ectQuery = (ExtendedCommonTermsQuery) parsedQuery;
         assertThat(ectQuery.getHighFreqMinimumNumberShouldMatchSpec(), nullValue());
         assertThat(ectQuery.getLowFreqMinimumNumberShouldMatchSpec(), equalTo("2"));
+
+        assertDeprecationWarning();
     }
 
     // see #11730
     public void testCommonTermsQuery4() throws IOException {
         Query parsedQuery = parseQuery(commonTermsQuery("field", "text")).toQuery(createShardContext());
         assertThat(parsedQuery, instanceOf(ExtendedCommonTermsQuery.class));
+
+        assertDeprecationWarning();
     }
 
     public void testParseFailsWithMultipleFields() throws IOException {
@@ -204,5 +238,11 @@ public class CommonTermsQueryBuilderTests extends AbstractQueryTestCase<CommonTe
                 "}";
         e = expectThrows(ParsingException.class, () -> parseQuery(shortJson));
         assertEquals("[common] query doesn't support multiple fields, found [message1] and [message2]", e.getMessage());
+
+        assertDeprecationWarning();
+    }
+
+    private void assertDeprecationWarning() {
+        assertWarnings("Deprecated field [common] used, replaced by [" + CommonTermsQueryBuilder.COMMON_TERMS_QUERY_DEPRECATION_MSG + "]");
     }
 }

+ 1 - 3
server/src/test/java/org/elasticsearch/index/query/CommonTermsQueryParserTests.java

@@ -22,10 +22,8 @@ package org.elasticsearch.index.query;
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.test.ESSingleNodeTestCase;
 
-import java.io.IOException;
-
 public class CommonTermsQueryParserTests extends ESSingleNodeTestCase {
-    public void testWhenParsedQueryIsNullNoNullPointerExceptionIsThrown() throws IOException {
+    public void testWhenParsedQueryIsNullNoNullPointerExceptionIsThrown() {
         final String index = "test-index";
         final String type = "test-type";
         client()

+ 1 - 5
server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java

@@ -124,10 +124,6 @@ public class MatchQueryBuilderTests extends FullTextQueryTestCase<MatchQueryBuil
             matchQuery.zeroTermsQuery(randomFrom(ZeroTermsQuery.ALL, ZeroTermsQuery.NONE));
         }
 
-        if (randomBoolean()) {
-            matchQuery.cutoffFrequency((float) 10 / randomIntBetween(1, 100));
-        }
-
         if (randomBoolean()) {
             matchQuery.autoGenerateSynonymsPhraseQuery(randomBoolean());
         }
@@ -478,7 +474,7 @@ public class MatchQueryBuilderTests extends FullTextQueryTestCase<MatchQueryBuil
         query.setAnalyzer(new MockGraphAnalyzer(createGiantGraphMultiTerms()));
         expectThrows(BooleanQuery.TooManyClauses.class, () -> query.parse(Type.PHRASE, STRING_FIELD_NAME, ""));
     }
-    
+
     private static class MockGraphAnalyzer extends Analyzer {
 
         CannedBinaryTokenStream tokenStream;

+ 0 - 3
server/src/test/java/org/elasticsearch/index/query/MultiMatchQueryBuilderTests.java

@@ -134,9 +134,6 @@ public class MultiMatchQueryBuilderTests extends FullTextQueryTestCase<MultiMatc
         if (randomBoolean()) {
             query.tieBreaker(randomFloat());
         }
-        if (randomBoolean() && query.type() != Type.BOOL_PREFIX) {
-            query.cutoffFrequency((float) 10 / randomIntBetween(1, 100));
-        }
         if (randomBoolean()) {
             query.zeroTermsQuery(randomFrom(MatchQuery.ZeroTermsQuery.NONE, MatchQuery.ZeroTermsQuery.ALL));
         }

+ 3 - 3
server/src/test/java/org/elasticsearch/search/SearchModuleTests.java

@@ -236,7 +236,7 @@ public class SearchModuleTests extends ESTestCase {
         assertSame(highlighters.get("custom"), customHighlighter);
     }
 
-    public void testRegisteredQueries() throws IOException {
+    public void testRegisteredQueries() {
         List<String> allSupportedQueries = new ArrayList<>();
         Collections.addAll(allSupportedQueries, NON_DEPRECATED_QUERIES);
         Collections.addAll(allSupportedQueries, DEPRECATED_QUERIES);
@@ -244,6 +244,7 @@ public class SearchModuleTests extends ESTestCase {
 
         Set<String> registeredNonDeprecated = module.getNamedXContents().stream()
                 .filter(e -> e.categoryClass.equals(QueryBuilder.class))
+                .filter(e -> e.name.getDeprecatedNames().length == 0)
                 .map(e -> e.name.getPreferredName())
                 .collect(toSet());
         Set<String> registeredAll = module.getNamedXContents().stream()
@@ -306,7 +307,6 @@ public class SearchModuleTests extends ESTestCase {
     private static final String[] NON_DEPRECATED_QUERIES = new String[] {
             "bool",
             "boosting",
-            "common",
             "constant_score",
             "dis_max",
             "exists",
@@ -354,7 +354,7 @@ public class SearchModuleTests extends ESTestCase {
     };
 
     //add here deprecated queries to make sure we log a deprecation warnings when they are used
-    private static final String[] DEPRECATED_QUERIES = new String[] {};
+    private static final String[] DEPRECATED_QUERIES = new String[] {"common"};
 
     /**
      * Dummy test {@link AggregationBuilder} used to test registering aggregation builders.

+ 2 - 31
server/src/test/java/org/elasticsearch/search/profile/query/RandomQueryGenerator.java

@@ -22,11 +22,9 @@ package org.elasticsearch.search.profile.query;
 import org.apache.lucene.util.English;
 import org.elasticsearch.common.unit.Fuzziness;
 import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.CommonTermsQueryBuilder;
 import org.elasticsearch.index.query.DisMaxQueryBuilder;
 import org.elasticsearch.index.query.FuzzyQueryBuilder;
 import org.elasticsearch.index.query.IdsQueryBuilder;
-import org.elasticsearch.index.query.Operator;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.RangeQueryBuilder;
@@ -72,7 +70,7 @@ public class RandomQueryGenerator {
     }
 
     private static QueryBuilder randomTerminalQuery(List<String> stringFields, List<String> numericFields, int numDocs) {
-        switch (randomIntBetween(0,6)) {
+        switch (randomIntBetween(0,5)) {
             case 0:
                 return randomTermQuery(stringFields, numDocs);
             case 1:
@@ -82,10 +80,8 @@ public class RandomQueryGenerator {
             case 3:
                 return QueryBuilders.matchAllQuery();
             case 4:
-                return randomCommonTermsQuery(stringFields, numDocs);
-            case 5:
                 return randomFuzzyQuery(stringFields);
-            case 6:
+            case 5:
                 return randomIDsQuery();
             default:
                 return randomTermQuery(stringFields, numDocs);
@@ -169,31 +165,6 @@ public class RandomQueryGenerator {
         return QueryBuilders.constantScoreQuery(randomQueryBuilder(stringFields, numericFields, numDocs, depth - 1));
     }
 
-    private static QueryBuilder randomCommonTermsQuery(List<String> fields, int numDocs) {
-        int numTerms = randomInt(numDocs);
-
-        QueryBuilder q = QueryBuilders.commonTermsQuery(randomField(fields), randomQueryString(numTerms));
-        if (randomBoolean()) {
-            ((CommonTermsQueryBuilder)q).boost(randomFloat());
-        }
-
-        if (randomBoolean()) {
-            ((CommonTermsQueryBuilder)q).cutoffFrequency(randomFloat());
-        }
-
-        if (randomBoolean()) {
-            ((CommonTermsQueryBuilder)q).highFreqMinimumShouldMatch(Integer.toString(randomInt(numTerms)))
-                    .highFreqOperator(randomBoolean() ? Operator.AND : Operator.OR);
-        }
-
-        if (randomBoolean()) {
-            ((CommonTermsQueryBuilder)q).lowFreqMinimumShouldMatch(Integer.toString(randomInt(numTerms)))
-                    .lowFreqOperator(randomBoolean() ? Operator.AND : Operator.OR);
-        }
-
-        return q;
-    }
-
     private static QueryBuilder randomFuzzyQuery(List<String> fields) {
 
         QueryBuilder q = QueryBuilders.fuzzyQuery(randomField(fields), randomQueryString(1));

+ 1 - 2
test/framework/src/main/java/org/elasticsearch/test/AbstractQueryTestCase.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.test;
 
 import com.fasterxml.jackson.core.io.JsonStringEncoder;
-
 import org.apache.lucene.search.BoostQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
@@ -165,7 +164,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
      * parse exception. Some specific objects do not cause any exception as they can hold arbitrary content; they can be
      * declared by overriding {@link #getObjectsHoldingArbitraryContent()}.
      */
-    public final void testUnknownObjectException() throws IOException {
+    public void testUnknownObjectException() throws IOException {
         Set<String> candidates = new HashSet<>();
         // Adds the valid query to the list of queries to modify and test
         candidates.add(createTestQueryBuilder().toString());