diff --git a/server/src/main/java/org/opensearch/search/builder/SearchSourceBuilder.java b/server/src/main/java/org/opensearch/search/builder/SearchSourceBuilder.java index e52520866f589..77d5567b924eb 100644 --- a/server/src/main/java/org/opensearch/search/builder/SearchSourceBuilder.java +++ b/server/src/main/java/org/opensearch/search/builder/SearchSourceBuilder.java @@ -1570,7 +1570,7 @@ public XContentBuilder innerToXContent(XContentBuilder builder, Params params) t if (derivedFieldsObject != null || derivedFields != null) { builder.startObject(DERIVED_FIELDS_FIELD.getPreferredName()); if (derivedFieldsObject != null) { - builder.map(derivedFieldsObject); + builder.mapContents(derivedFieldsObject); } if (derivedFields != null) { for (DerivedField derivedField : derivedFields) { @@ -1578,6 +1578,7 @@ public XContentBuilder innerToXContent(XContentBuilder builder, Params params) t } } builder.endObject(); + } return builder; diff --git a/server/src/test/java/org/opensearch/search/builder/SearchSourceBuilderTests.java b/server/src/test/java/org/opensearch/search/builder/SearchSourceBuilderTests.java index 6a5612232d334..eea7b1829e9b0 100644 --- a/server/src/test/java/org/opensearch/search/builder/SearchSourceBuilderTests.java +++ b/server/src/test/java/org/opensearch/search/builder/SearchSourceBuilderTests.java @@ -53,6 +53,7 @@ import org.opensearch.index.query.QueryRewriteContext; import org.opensearch.index.query.RandomQueryBuilder; import org.opensearch.index.query.Rewriteable; +import org.opensearch.script.Script; import org.opensearch.search.AbstractSearchTestCase; import org.opensearch.search.rescore.QueryRescorerBuilder; import org.opensearch.search.sort.FieldSortBuilder; @@ -311,7 +312,7 @@ public void testParseSort() throws IOException { } } - public void testDerivedFieldsParsing() throws IOException { + public void testDerivedFieldsParsingAndSerialization() throws IOException { { String restContent = "{\n" + " \"derived\": {\n" @@ -328,10 +329,29 @@ public void testDerivedFieldsParsing() throws IOException { + " \"match\": { \"content\": { \"query\": \"foo bar\" }}\n" + " }\n" + "}"; + + String expectedContent = + "{\"query\":{\"match\":{\"content\":{\"query\":\"foo bar\",\"operator\":\"OR\",\"prefix_length\":0,\"max_expansions\":50,\"fuzzy_transpositions\":true,\"lenient\":false,\"zero_terms_query\":\"NONE\",\"auto_generate_synonyms_phrase_query\":true,\"boost\":1.0}}}," + + "\"derived\":{" + + "\"duration\":{\"type\":\"long\",\"script\":\"emit(doc['test'])\"},\"ip_from_message\":{\"type\":\"keyword\",\"script\":\"emit(doc['message'])\"},\"derived_field\":{\"type\":\"keyword\",\"script\":{\"source\":\"emit(doc['message']\",\"lang\":\"painless\"}}}}"; + try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(parser); + searchSourceBuilder.derivedField("derived_field", "keyword", new Script("emit(doc['message']")); searchSourceBuilder = rewrite(searchSourceBuilder); assertEquals(2, searchSourceBuilder.getDerivedFieldsObject().size()); + assertEquals(1, searchSourceBuilder.getDerivedFields().size()); + + try (BytesStreamOutput output = new BytesStreamOutput()) { + searchSourceBuilder.writeTo(output); + try (StreamInput in = new NamedWriteableAwareStreamInput(output.bytes().streamInput(), namedWriteableRegistry)) { + SearchSourceBuilder deserializedBuilder = new SearchSourceBuilder(in); + String actualContent = deserializedBuilder.toString(); + assertEquals(expectedContent, actualContent); + assertEquals(searchSourceBuilder.hashCode(), deserializedBuilder.hashCode()); + assertNotSame(searchSourceBuilder, deserializedBuilder); + } + } } }