Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add script fields support for multi search request #632

Merged
merged 4 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -96,6 +97,8 @@ public class MultisearchBody implements JsonpSerializable {
@Nullable
private SourceConfig source;

private final Map<String, ScriptField> scriptFields;

// ---------------------------------------------------------------------------------------------

private MultisearchBody(Builder builder) {
Expand All @@ -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<Builder, ObjectBuilder<MultisearchBody>> fn) {
Expand Down Expand Up @@ -221,6 +224,10 @@ public final SourceConfig source() {
return this.source;
}

public final Map<String, ScriptField> scriptFields() {
return this.scriptFields;
}

/**
* Serialize this object to JSON.
*/
Expand Down Expand Up @@ -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<String, ScriptField> item0 : this.scriptFields.entrySet()) {
generator.writeKey(item0.getKey());
item0.getValue().serialize(generator, mapper);

}
generator.writeEnd();

}

}

// ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -364,6 +383,8 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder<M
@Nullable
private SourceConfig source;

private Map<String, ScriptField> scriptFields;
reta marked this conversation as resolved.
Show resolved Hide resolved


/**
* API name: {@code aggregations}
Expand Down Expand Up @@ -571,6 +592,29 @@ public final Builder source(Function<SourceConfig.Builder, ObjectBuilder<SourceC
return this.source(fn.apply(new SourceConfig.Builder()).build());
}

/**
* API name: {@code script_fields}
*/
public final Builder scriptFields(Map<String, ScriptField> 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<ScriptField.Builder, ObjectBuilder<ScriptField>> fn) {
return scriptFields(key, fn.apply(new ScriptField.Builder()).build());
}

/**
* Builds a {@link MultisearchBody}.
*
Expand Down Expand Up @@ -609,6 +653,8 @@ protected static void setupMultisearchBodyDeserializer(ObjectDeserializer<Multis
op.add(Builder::suggest, Suggester._DESERIALIZER, "suggest");
op.add(Builder::highlight, Highlight._DESERIALIZER, "highlight");
op.add(Builder::source, SourceConfig._DESERIALIZER, "_source");
op.add(Builder::scriptFields, JsonpDeserializer.stringMapDeserializer(ScriptField._DESERIALIZER),
"script_fields");

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
package org.opensearch.client.opensearch.integTest;

import org.junit.Test;
import org.opensearch.client.json.JsonData;
import org.opensearch.client.opensearch._types.FieldSort;
import org.opensearch.client.opensearch._types.FieldValue;
import org.opensearch.client.opensearch._types.InlineScript;
import org.opensearch.client.opensearch._types.Refresh;
import org.opensearch.client.opensearch._types.Script;
import org.opensearch.client.opensearch._types.ScriptField;
import org.opensearch.client.opensearch._types.SortOptions;
import org.opensearch.client.opensearch._types.SortOrder;
import org.opensearch.client.opensearch._types.query_dsl.FuzzyQuery;
Expand All @@ -28,7 +32,9 @@
import org.opensearch.client.util.ObjectBuilder;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public abstract class AbstractMultiSearchRequestIT extends OpenSearchJavaClientTestCase {
Expand Down Expand Up @@ -175,6 +181,42 @@ public void shouldReturnMultiSearchesSearchAfter() throws Exception {
assertEquals(1, response2.responses().get(0).result().hits().hits().size());
}

@Test
public void shouldReturnMultiSearchesScriptFields() throws Exception {
String index = "multiple_searches_request_script_fields";
createTestDocuments(index);

RequestItem sortedItemsQuery = createMSearchSortedFuzzyRequest();

MsearchResponse<ShopItem> 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<String, ScriptField> 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")
Copy link
Collaborator

@reta reta Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VachaShah that should make it (apologies for the wrong hint before):

Suggested change
.source("ctx._source.quantity += params.inc")
.source("doc['quantity'].value + params.inc")

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @reta, that works!!

.params("inc", JsonData.of(1))
.build())))
.build());


RequestItem requestItem = createMSearchQueryWithScriptFields("small", null, List.of(), scriptFields);

MsearchResponse<ShopItem> 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<ShopItem> response) {
List<Hit<ShopItem>> hitsWithHighlights = response.result().hits().hits();
Expand All @@ -198,6 +240,17 @@ private RequestItem createMSearchQuery(String itemSize) {
return createMSearchQuery(itemSize, null, List.of());
}

private RequestItem createMSearchQueryWithScriptFields(String itemSize, String fieldName, List<String> sources,
Map<String, ScriptField> 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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
* Run with: <c>./gradlew :samples:run -Dsamples.mainClass=Search</c>
*/
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;

Expand Down
Loading