diff --git a/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java index fb45597fb4771..f1a31db6125d2 100644 --- a/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/AbstractQueryBuilder.java @@ -78,13 +78,30 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws protected abstract void doXContent(XContentBuilder builder, Params params) throws IOException; - protected void printBoostAndQueryName(XContentBuilder builder) throws IOException { + /** + * Add {@code boost} and {@code query_name} to the builder. + * @deprecated use {@link #boostAndQueryNameToXContent} + */ + @Deprecated + protected final void printBoostAndQueryName(XContentBuilder builder) throws IOException { builder.field(BOOST_FIELD.getPreferredName(), boost); if (queryName != null) { builder.field(NAME_FIELD.getPreferredName(), queryName); } } + /** + * Add {@code boost} and {@code query_name} to the builder. + */ + protected final void boostAndQueryNameToXContent(XContentBuilder builder) throws IOException { + if (boost != DEFAULT_BOOST) { + builder.field(BOOST_FIELD.getPreferredName(), boost); + } + if (queryName != null) { + builder.field(NAME_FIELD.getPreferredName(), queryName); + } + } + @Override public final Query toQuery(SearchExecutionContext context) throws IOException { Query query = doToQuery(context); diff --git a/server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java index ccf33a2818d6a..0f8630ccbb030 100644 --- a/server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java @@ -328,15 +328,21 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio builder.startObject(fieldName); builder.field(QUERY_FIELD.getPreferredName(), value); - builder.field(OPERATOR_FIELD.getPreferredName(), operator.toString()); + if (operator != DEFAULT_OPERATOR) { + builder.field(OPERATOR_FIELD.getPreferredName(), operator.toString()); + } if (analyzer != null) { builder.field(ANALYZER_FIELD.getPreferredName(), analyzer); } if (fuzziness != null) { fuzziness.toXContent(builder, params); } - builder.field(PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength); - builder.field(MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions); + if (prefixLength != FuzzyQuery.defaultPrefixLength) { + builder.field(PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength); + } + if (maxExpansions != FuzzyQuery.defaultMaxExpansions) { + builder.field(MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions); + } if (minimumShouldMatch != null) { builder.field(MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), minimumShouldMatch); } @@ -344,11 +350,19 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio builder.field(FUZZY_REWRITE_FIELD.getPreferredName(), fuzzyRewrite); } // LUCENE 4 UPGRADE we need to document this & test this - builder.field(FUZZY_TRANSPOSITIONS_FIELD.getPreferredName(), fuzzyTranspositions); - builder.field(LENIENT_FIELD.getPreferredName(), lenient); - builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString()); - builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery); - printBoostAndQueryName(builder); + if (fuzzyTranspositions != FuzzyQuery.defaultTranspositions) { + builder.field(FUZZY_TRANSPOSITIONS_FIELD.getPreferredName(), fuzzyTranspositions); + } + if (lenient != MatchQueryParser.DEFAULT_LENIENCY) { + builder.field(LENIENT_FIELD.getPreferredName(), lenient); + } + if (false == zeroTermsQuery.equals(MatchQueryParser.DEFAULT_ZERO_TERMS_QUERY)) { + builder.field(ZERO_TERMS_QUERY_FIELD.getPreferredName(), zeroTermsQuery.toString()); + } + if (autoGenerateSynonymsPhraseQuery == false) { + builder.field(GENERATE_SYNONYMS_PHRASE_QUERY.getPreferredName(), autoGenerateSynonymsPhraseQuery); + } + boostAndQueryNameToXContent(builder); builder.endObject(); builder.endObject(); } diff --git a/server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java index b1819af573a4f..be96503a382b6 100644 --- a/server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java @@ -240,7 +240,11 @@ public void testIllegalValues() { } } - public void testSimpleMatchQuery() throws IOException { + public void testParseDefaultsRemoved() throws IOException { + /* + * This json includes many defaults. When we parse the query and then + * call toString on it all of the defaults are removed. + */ String json = """ { "match" : { @@ -258,12 +262,33 @@ public void testSimpleMatchQuery() throws IOException { } }"""; MatchQueryBuilder qb = (MatchQueryBuilder) parseQuery(json); - checkGeneratedJson(json, qb); + checkGeneratedJson(""" + { + "match": { + "message": { + "query": "to be or not to be", + "operator": "AND", + "zero_terms_query": "ALL" + } + } + }""", qb); assertEquals(json, "to be or not to be", qb.value()); assertEquals(json, Operator.AND, qb.operator()); } + public void testToXConentWithDefaults() throws IOException { + QueryBuilder query = new MatchQueryBuilder("foo", "bar"); + checkGeneratedJson(""" + { + "match": { + "foo": { + "query": "bar" + } + } + }""", query); + } + public void testFuzzinessOnNonStringField() throws Exception { MatchQueryBuilder query = new MatchQueryBuilder(INT_FIELD_NAME, 42); query.fuzziness(randomFuzziness(INT_FIELD_NAME)); diff --git a/server/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java index a9f121e9dc349..56a0845a6d7a3 100644 --- a/server/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/NestedQueryBuilderTests.java @@ -139,7 +139,11 @@ public void testValidate() { assertThat(e.getMessage(), equalTo("[nested] requires 'score_mode' field")); } - public void testFromJson() throws IOException { + public void testParseDefaultsRemoved() throws IOException { + /* + * This json includes many defaults. When we parse the query and then + * call toString on it all of the defaults are removed. + */ String json = """ { "nested" : { @@ -178,7 +182,34 @@ public void testFromJson() throws IOException { }"""; NestedQueryBuilder parsed = (NestedQueryBuilder) parseQuery(json); - checkGeneratedJson(json, parsed); + checkGeneratedJson(""" + { + "nested" : { + "query" : { + "bool" : { + "must" : [ { + "match" : { + "obj1.name" : { + "query" : "blue" + } + } + }, { + "range" : { + "obj1.count" : { + "gt" : 5, + "boost" : 1.0 + } + } + } ], + "boost" : 1.0 + } + }, + "path" : "obj1", + "ignore_unmapped" : false, + "score_mode" : "avg", + "boost" : 1.0 + } + }""", parsed); assertEquals(json, ScoreMode.Avg, parsed.scoreMode()); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/utils/XContentObjectTransformerTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/utils/XContentObjectTransformerTests.java index 38a1ab4f45c79..ae043a6e73de4 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/utils/XContentObjectTransformerTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/utils/XContentObjectTransformerTests.java @@ -59,23 +59,7 @@ public void testFromMap() throws IOException { assertXContentAreEqual(aggTransformer.fromMap(aggMap), aggMap); assertXContentAreEqual(aggTransformer.fromMap(aggMap), aggTransformer.toMap(aggTransformer.fromMap(aggMap))); - Map queryMap = Collections.singletonMap( - "match", - Collections.singletonMap("fieldName", new HashMap() { - { - // Add all the default fields so they are not added dynamically when the object is parsed - put("query", "fieldValue"); - put("operator", "OR"); - put("prefix_length", 0); - put("max_expansions", 50); - put("fuzzy_transpositions", true); - put("lenient", false); - put("zero_terms_query", "NONE"); - put("auto_generate_synonyms_phrase_query", true); - put("boost", 1.0); - } - }) - ); + Map queryMap = Map.of("match", Map.of("fieldName", Map.of("query", "fieldValue"))); XContentObjectTransformer queryBuilderTransformer = XContentObjectTransformer.queryBuilderTransformer( xContentRegistry()