From ce90d513837572901c4e97c533c410c04ae37f25 Mon Sep 17 00:00:00 2001 From: Vacha Shah Date: Thu, 21 Sep 2023 23:42:28 +0000 Subject: [PATCH 1/4] Adding script_fields support for mseearch request with tests Signed-off-by: Vacha Shah --- .../core/msearch/MultisearchBody.java | 48 ++++++++++++++++- .../AbstractMultiSearchRequestIT.java | 53 +++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/core/msearch/MultisearchBody.java b/java-client/src/main/java/org/opensearch/client/opensearch/core/msearch/MultisearchBody.java index f58b987ad2..e03538d484 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/core/msearch/MultisearchBody.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/core/msearch/MultisearchBody.java @@ -32,6 +32,7 @@ package org.opensearch.client.opensearch.core.msearch; +import org.opensearch.client.opensearch._types.ScriptField; import org.opensearch.client.opensearch._types.SortOptions; import org.opensearch.client.opensearch._types.aggregations.Aggregation; import org.opensearch.client.opensearch._types.query_dsl.Query; @@ -96,6 +97,8 @@ public class MultisearchBody implements JsonpSerializable { @Nullable private SourceConfig source; + private final Map scriptFields; + // --------------------------------------------------------------------------------------------- private MultisearchBody(Builder builder) { @@ -113,7 +116,7 @@ private MultisearchBody(Builder builder) { this.suggest = builder.suggest; this.highlight = builder.highlight; this.source = builder.source; - + this.scriptFields = ApiTypeHelper.unmodifiable(builder.scriptFields); } public static MultisearchBody of(Function> fn) { @@ -221,6 +224,10 @@ public final SourceConfig source() { return this.source; } + public final Map scriptFields() { + return this.scriptFields; + } + /** * Serialize this object to JSON. */ @@ -316,6 +323,18 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { } + if (ApiTypeHelper.isDefined(this.scriptFields)) { + generator.writeKey("script_fields"); + generator.writeStartObject(); + for (Map.Entry item0 : this.scriptFields.entrySet()) { + generator.writeKey(item0.getKey()); + item0.getValue().serialize(generator, mapper); + + } + generator.writeEnd(); + + } + } // --------------------------------------------------------------------------------------------- @@ -364,6 +383,8 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder scriptFields; + /** * API name: {@code aggregations} @@ -571,6 +592,29 @@ public final Builder source(Function map) { + this.scriptFields = _mapPutAll(this.scriptFields, map); + return this; + } + + /** + * API name: {@code script_fields} + */ + public final Builder scriptFields(String key, ScriptField value) { + this.scriptFields = _mapPut(this.scriptFields, key, value); + return this; + } + + /** + * API name: {@code script_fields} + */ + public final Builder scriptFields(String key, Function> fn) { + return scriptFields(key, fn.apply(new ScriptField.Builder()).build()); + } + /** * Builds a {@link MultisearchBody}. * @@ -609,6 +653,8 @@ protected static void setupMultisearchBodyDeserializer(ObjectDeserializer response = sendMSearchRequest(index, List.of(sortedItemsQuery)); + assertEquals(1, response.responses().size()); + var hits = response.responses().get(0).result().hits().hits(); + assertEquals(3, hits.size()); + assertNull(hits.get(0).score()); + assertNull(hits.get(1).score()); + assertNull(hits.get(2).score()); + + System.out.println(response.responses().get(0).result().hits().hits().get(0).source()); + System.out.println(response.responses().get(0).result().hits().hits().get(1).source()); + + Map scriptFields = new HashMap<>(); + scriptFields.put("test1", new ScriptField.Builder().script(Script.of(s -> s.inline(new InlineScript.Builder() + .lang("painless") + .source("ctx._source.quantity += params.inc") + .params("inc", JsonData.of(1)) + .build()))) + .build()); + + + RequestItem requestItem = createMSearchQueryWithScriptFields("small", null, List.of(), scriptFields); + + MsearchResponse responseTrackingScore = sendMSearchRequest(index, List.of(requestItem)); + // System.out.println("Search response: " + responseTrackingScore.responses().size()); + // System.out.println(responseTrackingScore.responses().get(0).failure().error().reason()); + // System.out.println(responseTrackingScore.responses().get(0).failure().error().stackTrace()); + // System.out.println(responseTrackingScore.responses().get(0).failure().status()); + } + private void assertResponseSources(MultiSearchResponseItem response) { List> hitsWithHighlights = response.result().hits().hits(); @@ -198,6 +241,16 @@ private RequestItem createMSearchQuery(String itemSize) { return createMSearchQuery(itemSize, null, List.of()); } + private RequestItem createMSearchQueryWithScriptFields(String itemSize, String fieldName, List sources, Map scriptFields) { + return RequestItem.of(item -> item.header(header -> header) + .body(body -> body.query(createItemSizeSearchQuery(itemSize)) + .highlight(createHighlight(fieldName)) + .source(createSourcesConfig(sources)) + .scriptFields(scriptFields) + ) + ); + } + private RequestItem createMSearchQueryWithHighlight(String itemSize) { return createMSearchQuery(itemSize, "size", List.of()); } From 6efa86c8ad060d1e45931a84a39ff352b45a0a36 Mon Sep 17 00:00:00 2001 From: Vacha Shah Date: Thu, 21 Sep 2023 23:42:43 +0000 Subject: [PATCH 2/4] Fixing logger in Search sample Signed-off-by: Vacha Shah --- samples/src/main/java/org/opensearch/client/samples/Search.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/src/main/java/org/opensearch/client/samples/Search.java b/samples/src/main/java/org/opensearch/client/samples/Search.java index ccc1acb679..ea41bfc48c 100644 --- a/samples/src/main/java/org/opensearch/client/samples/Search.java +++ b/samples/src/main/java/org/opensearch/client/samples/Search.java @@ -47,7 +47,7 @@ * Run with: ./gradlew :samples:run -Dsamples.mainClass=Search */ public class Search { - private static final Logger LOGGER = LogManager.getLogger(IndexingBasics.class); + private static final Logger LOGGER = LogManager.getLogger(Search.class); private static OpenSearchClient client; From 418c6cd40d1454953af1e44f526dc6c42b51a64f Mon Sep 17 00:00:00 2001 From: Vacha Shah Date: Thu, 21 Sep 2023 23:54:37 +0000 Subject: [PATCH 3/4] Fixing build Signed-off-by: Vacha Shah --- CHANGELOG.md | 1 + .../opensearch/integTest/AbstractMultiSearchRequestIT.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f52cd35e9..83029e0ff3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Added - Added support for "smartcn" analyzer ([#605](https://github.com/opensearch-project/opensearch-java/pull/605)) +- Added support for "script_fields" in multi search request ([#632](https://github.com/opensearch-project/opensearch-java/pull/632)) ### Dependencies diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java index 1507ceaca7..4418e0f744 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java @@ -32,7 +32,6 @@ import org.opensearch.client.util.ObjectBuilder; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -241,7 +240,8 @@ private RequestItem createMSearchQuery(String itemSize) { return createMSearchQuery(itemSize, null, List.of()); } - private RequestItem createMSearchQueryWithScriptFields(String itemSize, String fieldName, List sources, Map scriptFields) { + private RequestItem createMSearchQueryWithScriptFields(String itemSize, String fieldName, List sources, + Map scriptFields) { return RequestItem.of(item -> item.header(header -> header) .body(body -> body.query(createItemSizeSearchQuery(itemSize)) .highlight(createHighlight(fieldName)) From 76d78ec38538f89a40a4f9566074eff3f11b55a0 Mon Sep 17 00:00:00 2001 From: Vacha Shah Date: Fri, 22 Sep 2023 22:27:31 +0000 Subject: [PATCH 4/4] Fixing tests Signed-off-by: Vacha Shah --- .../AbstractMultiSearchRequestIT.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java index 4418e0f744..c082d9b043 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java @@ -31,6 +31,9 @@ import org.opensearch.client.opensearch.core.search.SourceConfig; import org.opensearch.client.util.ObjectBuilder; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -196,25 +199,27 @@ public void shouldReturnMultiSearchesScriptFields() throws Exception { assertNull(hits.get(1).score()); assertNull(hits.get(2).score()); - System.out.println(response.responses().get(0).result().hits().hits().get(0).source()); - System.out.println(response.responses().get(0).result().hits().hits().get(1).source()); - Map scriptFields = new HashMap<>(); - scriptFields.put("test1", new ScriptField.Builder().script(Script.of(s -> s.inline(new InlineScript.Builder() + scriptFields.put("quantity", new ScriptField.Builder().script(Script.of(s -> s.inline(new InlineScript.Builder() .lang("painless") - .source("ctx._source.quantity += params.inc") + .source("doc['quantity'].value + params.inc") .params("inc", JsonData.of(1)) .build()))) .build()); - RequestItem requestItem = createMSearchQueryWithScriptFields("small", null, List.of(), scriptFields); + RequestItem requestItem = createMSearchQueryWithScriptFields("small", scriptFields); + + MsearchResponse responseWithScriptFields = sendMSearchRequest(index, List.of(requestItem)); + var hitsWithScriptFields = responseWithScriptFields.responses().get(0).result().hits().hits(); + assertEquals(2, hitsWithScriptFields.size()); + // validating that the quantity for small items is increased by 1 + ObjectMapper mapper = new ObjectMapper(); + JsonNode node = mapper.readTree(hitsWithScriptFields.get(0).fields().get("quantity").toString()); + assertEquals(2, (int) mapper.treeToValue(node.get(0), int.class)); - MsearchResponse responseTrackingScore = sendMSearchRequest(index, List.of(requestItem)); - // System.out.println("Search response: " + responseTrackingScore.responses().size()); - // System.out.println(responseTrackingScore.responses().get(0).failure().error().reason()); - // System.out.println(responseTrackingScore.responses().get(0).failure().error().stackTrace()); - // System.out.println(responseTrackingScore.responses().get(0).failure().status()); + node = mapper.readTree(hitsWithScriptFields.get(1).fields().get("quantity").toString()); + assertEquals(3, (int) mapper.treeToValue(node.get(0), int.class)); } @@ -240,12 +245,9 @@ private RequestItem createMSearchQuery(String itemSize) { return createMSearchQuery(itemSize, null, List.of()); } - private RequestItem createMSearchQueryWithScriptFields(String itemSize, String fieldName, List sources, - Map scriptFields) { + private RequestItem createMSearchQueryWithScriptFields(String itemSize, Map scriptFields) { return RequestItem.of(item -> item.header(header -> header) .body(body -> body.query(createItemSizeSearchQuery(itemSize)) - .highlight(createHighlight(fieldName)) - .source(createSourcesConfig(sources)) .scriptFields(scriptFields) ) );