Skip to content

Commit a3aed38

Browse files
authored
Add missed fields to MultisearchBody: seqNoPrimaryTerm, storedFields, explain, fields, indicesBoost (opensearch-project#914) (opensearch-project#915)
Signed-off-by: Andriy Redko <[email protected]> (cherry picked from commit 5714df5)
1 parent 8983680 commit a3aed38

File tree

3 files changed

+302
-1
lines changed

3 files changed

+302
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
44
## [Unreleased 2.x]
55
### Added
66
- Add xy_shape property ([#884](https://github.com/opensearch-project/opensearch-java/pull/885))
7+
- Add missed fields to MultisearchBody: seqNoPrimaryTerm, storedFields, explain, fields, indicesBoost ([#914](https://github.com/opensearch-project/opensearch-java/pull/914))
78

89
### Dependencies
910
- Bumps `io.github.classgraph:classgraph` from 4.8.161 to 4.8.165

java-client/src/main/java/org/opensearch/client/opensearch/core/msearch/MultisearchBody.java

+258-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@
4646
import org.opensearch.client.opensearch._types.ScriptField;
4747
import org.opensearch.client.opensearch._types.SortOptions;
4848
import org.opensearch.client.opensearch._types.aggregations.Aggregation;
49+
import org.opensearch.client.opensearch._types.query_dsl.FieldAndFormat;
4950
import org.opensearch.client.opensearch._types.query_dsl.Query;
51+
import org.opensearch.client.opensearch.core.SearchRequest.Builder;
5052
import org.opensearch.client.opensearch.core.search.Highlight;
5153
import org.opensearch.client.opensearch.core.search.SourceConfig;
5254
import org.opensearch.client.opensearch.core.search.Suggester;
@@ -97,6 +99,18 @@ public class MultisearchBody implements JsonpSerializable {
9799

98100
private final Map<String, ScriptField> scriptFields;
99101

102+
@Nullable
103+
private final Boolean seqNoPrimaryTerm;
104+
105+
private final List<String> storedFields;
106+
107+
@Nullable
108+
private final Boolean explain;
109+
110+
private final List<FieldAndFormat> fields;
111+
112+
private final List<Map<String, Double>> indicesBoost;
113+
100114
// ---------------------------------------------------------------------------------------------
101115

102116
private MultisearchBody(Builder builder) {
@@ -115,6 +129,11 @@ private MultisearchBody(Builder builder) {
115129
this.highlight = builder.highlight;
116130
this.source = builder.source;
117131
this.scriptFields = ApiTypeHelper.unmodifiable(builder.scriptFields);
132+
this.seqNoPrimaryTerm = builder.seqNoPrimaryTerm;
133+
this.storedFields = ApiTypeHelper.unmodifiable(builder.storedFields);
134+
this.explain = builder.explain;
135+
this.fields = ApiTypeHelper.unmodifiable(builder.fields);
136+
this.indicesBoost = ApiTypeHelper.unmodifiable(builder.indicesBoost);
118137
}
119138

120139
public static MultisearchBody of(Function<Builder, ObjectBuilder<MultisearchBody>> fn) {
@@ -226,6 +245,59 @@ public final Map<String, ScriptField> scriptFields() {
226245
return this.scriptFields;
227246
}
228247

248+
/**
249+
* If true, returns sequence number and primary term of the last modification of
250+
* each hit. See Optimistic concurrency control.
251+
* <p>
252+
* API name: {@code seq_no_primary_term}
253+
*/
254+
@Nullable
255+
public final Boolean seqNoPrimaryTerm() {
256+
return this.seqNoPrimaryTerm;
257+
}
258+
259+
/**
260+
* List of stored fields to return as part of a hit. If no fields are specified,
261+
* no stored fields are included in the response. If this field is specified,
262+
* the _source parameter defaults to false. You can pass _source: true to return
263+
* both source fields and stored fields in the search response.
264+
* <p>
265+
* API name: {@code stored_fields}
266+
*/
267+
public final List<String> storedFields() {
268+
return this.storedFields;
269+
}
270+
271+
/**
272+
* If true, returns detailed information about score computation as part of a
273+
* hit.
274+
* <p>
275+
* API name: {@code explain}
276+
*/
277+
@Nullable
278+
public final Boolean explain() {
279+
return this.explain;
280+
}
281+
282+
/**
283+
* Array of wildcard (*) patterns. The request returns values for field names
284+
* matching these patterns in the hits.fields property of the response.
285+
* <p>
286+
* API name: {@code fields}
287+
*/
288+
public final List<FieldAndFormat> fields() {
289+
return this.fields;
290+
}
291+
292+
/**
293+
* Boosts the _score of documents from specified indices.
294+
* <p>
295+
* API name: {@code indices_boost}
296+
*/
297+
public final List<Map<String, Double>> indicesBoost() {
298+
return this.indicesBoost;
299+
}
300+
229301
/**
230302
* Serialize this object to JSON.
231303
*/
@@ -333,6 +405,54 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
333405

334406
}
335407

408+
if (this.seqNoPrimaryTerm != null) {
409+
generator.writeKey("seq_no_primary_term");
410+
generator.write(this.seqNoPrimaryTerm);
411+
}
412+
413+
if (ApiTypeHelper.isDefined(this.storedFields)) {
414+
generator.writeKey("stored_fields");
415+
generator.writeStartArray();
416+
for (String item0 : this.storedFields) {
417+
generator.write(item0);
418+
419+
}
420+
generator.writeEnd();
421+
}
422+
423+
if (this.explain != null) {
424+
generator.writeKey("explain");
425+
generator.write(this.explain);
426+
427+
}
428+
429+
if (ApiTypeHelper.isDefined(this.fields)) {
430+
generator.writeKey("fields");
431+
generator.writeStartArray();
432+
for (FieldAndFormat item0 : this.fields) {
433+
item0.serialize(generator, mapper);
434+
435+
}
436+
generator.writeEnd();
437+
}
438+
439+
if (ApiTypeHelper.isDefined(this.indicesBoost)) {
440+
generator.writeKey("indices_boost");
441+
generator.writeStartArray();
442+
for (Map<String, Double> item0 : this.indicesBoost) {
443+
generator.writeStartObject();
444+
if (item0 != null) {
445+
for (Map.Entry<String, Double> item1 : item0.entrySet()) {
446+
generator.writeKey(item1.getKey());
447+
generator.write(item1.getValue());
448+
449+
}
450+
}
451+
generator.writeEnd();
452+
453+
}
454+
generator.writeEnd();
455+
}
336456
}
337457

338458
// ---------------------------------------------------------------------------------------------
@@ -383,6 +503,21 @@ public static class Builder extends ObjectBuilderBase implements ObjectBuilder<M
383503

384504
private Map<String, ScriptField> scriptFields;
385505

506+
@Nullable
507+
private Boolean seqNoPrimaryTerm;
508+
509+
@Nullable
510+
private List<String> storedFields;
511+
512+
@Nullable
513+
private Boolean explain;
514+
515+
@Nullable
516+
private List<FieldAndFormat> fields;
517+
518+
@Nullable
519+
private List<Map<String, Double>> indicesBoost;
520+
386521
/**
387522
* API name: {@code aggregations}
388523
* <p>
@@ -612,6 +747,120 @@ public final Builder scriptFields(String key, Function<ScriptField.Builder, Obje
612747
return scriptFields(key, fn.apply(new ScriptField.Builder()).build());
613748
}
614749

750+
/**
751+
* If true, returns sequence number and primary term of the last modification of
752+
* each hit. See Optimistic concurrency control.
753+
* <p>
754+
* API name: {@code seq_no_primary_term}
755+
*/
756+
public final Builder seqNoPrimaryTerm(@Nullable Boolean value) {
757+
this.seqNoPrimaryTerm = value;
758+
return this;
759+
}
760+
761+
/**
762+
* List of stored fields to return as part of a hit. If no fields are specified,
763+
* no stored fields are included in the response. If this field is specified,
764+
* the _source parameter defaults to false. You can pass _source: true to return
765+
* both source fields and stored fields in the search response.
766+
* <p>
767+
* API name: {@code stored_fields}
768+
* <p>
769+
* Adds all elements of <code>list</code> to <code>storedFields</code>.
770+
*/
771+
public final Builder storedFields(List<String> list) {
772+
this.storedFields = _listAddAll(this.storedFields, list);
773+
return this;
774+
}
775+
776+
/**
777+
* List of stored fields to return as part of a hit. If no fields are specified,
778+
* no stored fields are included in the response. If this field is specified,
779+
* the _source parameter defaults to false. You can pass _source: true to return
780+
* both source fields and stored fields in the search response.
781+
* <p>
782+
* API name: {@code stored_fields}
783+
* <p>
784+
* Adds one or more values to <code>storedFields</code>.
785+
*/
786+
public final Builder storedFields(String value, String... values) {
787+
this.storedFields = _listAdd(this.storedFields, value, values);
788+
return this;
789+
}
790+
791+
/**
792+
* If true, returns detailed information about score computation as part of a
793+
* hit.
794+
* <p>
795+
* API name: {@code explain}
796+
*/
797+
public final Builder explain(@Nullable Boolean value) {
798+
this.explain = value;
799+
return this;
800+
}
801+
802+
/**
803+
* Array of wildcard (*) patterns. The request returns values for field names
804+
* matching these patterns in the hits.fields property of the response.
805+
* <p>
806+
* API name: {@code fields}
807+
* <p>
808+
* Adds all elements of <code>list</code> to <code>fields</code>.
809+
*/
810+
public final Builder fields(List<FieldAndFormat> list) {
811+
this.fields = _listAddAll(this.fields, list);
812+
return this;
813+
}
814+
815+
/**
816+
* Array of wildcard (*) patterns. The request returns values for field names
817+
* matching these patterns in the hits.fields property of the response.
818+
* <p>
819+
* API name: {@code fields}
820+
* <p>
821+
* Adds one or more values to <code>fields</code>.
822+
*/
823+
public final Builder fields(FieldAndFormat value, FieldAndFormat... values) {
824+
this.fields = _listAdd(this.fields, value, values);
825+
return this;
826+
}
827+
828+
/**
829+
* Array of wildcard (*) patterns. The request returns values for field names
830+
* matching these patterns in the hits.fields property of the response.
831+
* <p>
832+
* API name: {@code fields}
833+
* <p>
834+
* Adds a value to <code>fields</code> using a builder lambda.
835+
*/
836+
public final Builder fields(Function<FieldAndFormat.Builder, ObjectBuilder<FieldAndFormat>> fn) {
837+
return fields(fn.apply(new FieldAndFormat.Builder()).build());
838+
}
839+
840+
/**
841+
* Boosts the _score of documents from specified indices.
842+
* <p>
843+
* API name: {@code indices_boost}
844+
* <p>
845+
* Adds all elements of <code>list</code> to <code>indicesBoost</code>.
846+
*/
847+
public final Builder indicesBoost(List<Map<String, Double>> list) {
848+
this.indicesBoost = _listAddAll(this.indicesBoost, list);
849+
return this;
850+
}
851+
852+
/**
853+
* Boosts the _score of documents from specified indices.
854+
* <p>
855+
* API name: {@code indices_boost}
856+
* <p>
857+
* Adds one or more values to <code>indicesBoost</code>.
858+
*/
859+
public final Builder indicesBoost(Map<String, Double> value, Map<String, Double>... values) {
860+
this.indicesBoost = _listAdd(this.indicesBoost, value, values);
861+
return this;
862+
}
863+
615864
/**
616865
* Builds a {@link MultisearchBody}.
617866
*
@@ -651,7 +900,15 @@ protected static void setupMultisearchBodyDeserializer(ObjectDeserializer<Multis
651900
op.add(Builder::highlight, Highlight._DESERIALIZER, "highlight");
652901
op.add(Builder::source, SourceConfig._DESERIALIZER, "_source");
653902
op.add(Builder::scriptFields, JsonpDeserializer.stringMapDeserializer(ScriptField._DESERIALIZER), "script_fields");
654-
903+
op.add(Builder::seqNoPrimaryTerm, JsonpDeserializer.booleanDeserializer(), "seq_no_primary_term");
904+
op.add(Builder::storedFields, JsonpDeserializer.arrayDeserializer(JsonpDeserializer.stringDeserializer()), "stored_fields");
905+
op.add(Builder::explain, JsonpDeserializer.booleanDeserializer(), "explain");
906+
op.add(Builder::fields, JsonpDeserializer.arrayDeserializer(FieldAndFormat._DESERIALIZER), "fields");
907+
op.add(
908+
Builder::indicesBoost,
909+
JsonpDeserializer.arrayDeserializer(JsonpDeserializer.stringMapDeserializer(JsonpDeserializer.doubleDeserializer())),
910+
"indices_boost"
911+
);
655912
}
656913

657914
}

java-client/src/test/java11/org/opensearch/client/opensearch/integTest/AbstractMultiSearchRequestIT.java

+43
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88

99
package org.opensearch.client.opensearch.integTest;
1010

11+
import static org.hamcrest.Matchers.hasKey;
12+
1113
import com.fasterxml.jackson.databind.JsonNode;
1214
import com.fasterxml.jackson.databind.ObjectMapper;
1315
import java.io.IOException;
16+
import java.util.Collections;
1417
import java.util.HashMap;
1518
import java.util.List;
1619
import java.util.Map;
@@ -25,6 +28,7 @@
2528
import org.opensearch.client.opensearch._types.ScriptField;
2629
import org.opensearch.client.opensearch._types.SortOptions;
2730
import org.opensearch.client.opensearch._types.SortOrder;
31+
import org.opensearch.client.opensearch._types.query_dsl.FieldAndFormat;
2832
import org.opensearch.client.opensearch._types.query_dsl.FuzzyQuery;
2933
import org.opensearch.client.opensearch._types.query_dsl.Query;
3034
import org.opensearch.client.opensearch._types.query_dsl.TermQuery;
@@ -226,6 +230,45 @@ public void shouldReturnMultiSearchesScriptFields() throws Exception {
226230
assertEquals(3, (int) mapper.treeToValue(node.get(0), int.class));
227231
}
228232

233+
@Test
234+
public void shouldReturnMultiSearchesFields() throws Exception {
235+
String index = "multiple_searches_request_fields";
236+
createTestDocuments(index);
237+
238+
RequestItem sortedItemsQuery = createMSearchFuzzyRequest(b -> b.fields(FieldAndFormat.of(f -> f.field("name"))));
239+
240+
MsearchResponse<ShopItem> response = sendMSearchRequest(index, List.of(sortedItemsQuery));
241+
assertEquals(1, response.responses().size());
242+
assertEquals(3, response.responses().get(0).result().hits().hits().size());
243+
assertThat(response.responses().get(0).result().hits().hits().get(0).fields(), hasKey("name"));
244+
assertThat(response.responses().get(0).result().hits().hits().get(1).fields(), hasKey("name"));
245+
assertThat(response.responses().get(0).result().hits().hits().get(2).fields(), hasKey("name"));
246+
}
247+
248+
@Test
249+
public void shouldReturnMultiSearchesStoredFields() throws Exception {
250+
String index = "multiple_searches_request_stored_fields";
251+
createTestDocuments(index);
252+
253+
RequestItem sortedItemsQuery = createMSearchFuzzyRequest(b -> b.storedFields("name"));
254+
255+
MsearchResponse<ShopItem> response = sendMSearchRequest(index, List.of(sortedItemsQuery));
256+
assertEquals(1, response.responses().size());
257+
assertEquals(3, response.responses().get(0).result().hits().hits().size());
258+
}
259+
260+
@Test
261+
public void shouldReturnMultiSearchesIndicesBoost() throws Exception {
262+
String index = "multiple_searches_request_indices_boost";
263+
createTestDocuments(index);
264+
265+
RequestItem sortedItemsQuery = createMSearchFuzzyRequest(b -> b.indicesBoost(Collections.singletonMap(index, 2d)));
266+
267+
MsearchResponse<ShopItem> response = sendMSearchRequest(index, List.of(sortedItemsQuery));
268+
assertEquals(1, response.responses().size());
269+
assertEquals(3, response.responses().get(0).result().hits().hits().size());
270+
}
271+
229272
private void assertResponseSources(MultiSearchResponseItem<ShopItem> response) {
230273
List<Hit<ShopItem>> hitsWithHighlights = response.result().hits().hits();
231274
assertEquals(2, hitsWithHighlights.size());

0 commit comments

Comments
 (0)