Skip to content

Commit fa0c774

Browse files
committed
Add copy constructor to SearchRequest (#36641)
For cross cluster search alternate execution mode (see #32125), we will need to take a search request that spans across multiple clusters (based on index prefixes e.g. cluster1:index, cluster2:index etc.) and split it into multiple search requests to be sent to each cluster. A copy constructor added to `SearchRequest` would make that easy and well maintainable in the future. Something along the same lines already happens in `BulkByScrollParallelizationHelper`, but the corresponding code went outdated as some new fields were added to `SearchRequest` which were not added to the bulk by scroll code. A copy constructor helps making the task of copying a search request maintainable over time.
1 parent e939f3d commit fa0c774

File tree

3 files changed

+41
-45
lines changed

3 files changed

+41
-45
lines changed

modules/reindex/src/main/java/org/elasticsearch/index/reindex/BulkByScrollParallelizationHelper.java

+3-13
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,9 @@ static SearchRequest[] sliceIntoSubRequests(SearchRequest request, String field,
154154
}
155155
slicedSource = request.source().copyWithNewSlice(sliceBuilder);
156156
}
157-
slices[slice] = new SearchRequest()
158-
.source(slicedSource)
159-
.searchType(request.searchType())
160-
.indices(request.indices())
161-
.types(request.types())
162-
.routing(request.routing())
163-
.preference(request.preference())
164-
.requestCache(request.requestCache())
165-
.scroll(request.scroll())
166-
.indicesOptions(request.indicesOptions());
167-
if (request.allowPartialSearchResults() != null) {
168-
slices[slice].allowPartialSearchResults(request.allowPartialSearchResults());
169-
}
157+
SearchRequest searchRequest = new SearchRequest(request);
158+
searchRequest.source(slicedSource);
159+
slices[slice] = searchRequest;
170160
}
171161
return slices;
172162
}

server/src/main/java/org/elasticsearch/action/search/SearchRequest.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ public final class SearchRequest extends ActionRequest implements IndicesRequest
7979
private Boolean requestCache;
8080

8181
private Boolean allowPartialSearchResults;
82-
83-
82+
8483
private Scroll scroll;
8584

8685
private int batchedReduceSize = DEFAULT_BATCHED_REDUCE_SIZE;
@@ -98,6 +97,25 @@ public final class SearchRequest extends ActionRequest implements IndicesRequest
9897
public SearchRequest() {
9998
}
10099

100+
/**
101+
* Constructs a new search request from the provided search request
102+
*/
103+
public SearchRequest(SearchRequest searchRequest) {
104+
this.allowPartialSearchResults = searchRequest.allowPartialSearchResults;
105+
this.batchedReduceSize = searchRequest.batchedReduceSize;
106+
this.indices = searchRequest.indices;
107+
this.indicesOptions = searchRequest.indicesOptions;
108+
this.maxConcurrentShardRequests = searchRequest.maxConcurrentShardRequests;
109+
this.preference = searchRequest.preference;
110+
this.preFilterShardSize = searchRequest.preFilterShardSize;
111+
this.requestCache = searchRequest.requestCache;
112+
this.routing = searchRequest.routing;
113+
this.scroll = searchRequest.scroll;
114+
this.searchType = searchRequest.searchType;
115+
this.source = searchRequest.source;
116+
this.types = searchRequest.types;
117+
}
118+
101119
/**
102120
* Constructs a new search request against the indices. No indices provided here means that search
103121
* will run against all indices.

server/src/test/java/org/elasticsearch/search/SearchRequestTests.java

+18-30
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@
1919

2020
package org.elasticsearch.search;
2121

22+
import org.elasticsearch.Version;
2223
import org.elasticsearch.action.ActionRequestValidationException;
2324
import org.elasticsearch.action.search.SearchRequest;
2425
import org.elasticsearch.action.search.SearchType;
2526
import org.elasticsearch.action.support.IndicesOptions;
26-
import org.elasticsearch.common.io.stream.BytesStreamOutput;
27-
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
28-
import org.elasticsearch.common.io.stream.StreamInput;
2927
import org.elasticsearch.common.unit.TimeValue;
3028
import org.elasticsearch.common.util.ArrayUtils;
3129
import org.elasticsearch.index.query.QueryBuilders;
3230
import org.elasticsearch.search.builder.SearchSourceBuilder;
3331
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
32+
import org.elasticsearch.test.ESTestCase;
3433

3534
import java.io.IOException;
3635
import java.util.ArrayList;
@@ -42,16 +41,10 @@ public class SearchRequestTests extends AbstractSearchTestCase {
4241

4342
public void testSerialization() throws Exception {
4443
SearchRequest searchRequest = createSearchRequest();
45-
try (BytesStreamOutput output = new BytesStreamOutput()) {
46-
searchRequest.writeTo(output);
47-
try (StreamInput in = new NamedWriteableAwareStreamInput(output.bytes().streamInput(), namedWriteableRegistry)) {
48-
SearchRequest deserializedRequest = new SearchRequest();
49-
deserializedRequest.readFrom(in);
50-
assertEquals(deserializedRequest, searchRequest);
51-
assertEquals(deserializedRequest.hashCode(), searchRequest.hashCode());
52-
assertNotSame(deserializedRequest, searchRequest);
53-
}
54-
}
44+
SearchRequest deserializedRequest = copyStreamable(searchRequest, namedWriteableRegistry, SearchRequest::new, Version.CURRENT);
45+
assertEquals(deserializedRequest, searchRequest);
46+
assertEquals(deserializedRequest.hashCode(), searchRequest.hashCode());
47+
assertNotSame(deserializedRequest, searchRequest);
5548
}
5649

5750
public void testIllegalArguments() {
@@ -139,11 +132,19 @@ public void testValidate() throws IOException {
139132

140133
}
141134

135+
public void testCopyConstructor() throws IOException {
136+
SearchRequest searchRequest = createSearchRequest();
137+
SearchRequest deserializedRequest = copyStreamable(searchRequest, namedWriteableRegistry, SearchRequest::new, Version.CURRENT);
138+
assertEquals(deserializedRequest, searchRequest);
139+
assertEquals(deserializedRequest.hashCode(), searchRequest.hashCode());
140+
assertNotSame(deserializedRequest, searchRequest);
141+
}
142+
142143
public void testEqualsAndHashcode() throws IOException {
143144
checkEqualsAndHashCode(createSearchRequest(), SearchRequestTests::copyRequest, this::mutate);
144145
}
145146

146-
private SearchRequest mutate(SearchRequest searchRequest) throws IOException {
147+
private SearchRequest mutate(SearchRequest searchRequest) {
147148
SearchRequest mutation = copyRequest(searchRequest);
148149
List<Runnable> mutators = new ArrayList<>();
149150
mutators.add(() -> mutation.indices(ArrayUtils.concat(searchRequest.indices(), new String[] { randomAlphaOfLength(10) })));
@@ -152,7 +153,7 @@ private SearchRequest mutate(SearchRequest searchRequest) throws IOException {
152153
mutators.add(() -> mutation.types(ArrayUtils.concat(searchRequest.types(), new String[] { randomAlphaOfLength(10) })));
153154
mutators.add(() -> mutation.preference(randomValueOtherThan(searchRequest.preference(), () -> randomAlphaOfLengthBetween(3, 10))));
154155
mutators.add(() -> mutation.routing(randomValueOtherThan(searchRequest.routing(), () -> randomAlphaOfLengthBetween(3, 10))));
155-
mutators.add(() -> mutation.requestCache((randomValueOtherThan(searchRequest.requestCache(), () -> randomBoolean()))));
156+
mutators.add(() -> mutation.requestCache((randomValueOtherThan(searchRequest.requestCache(), ESTestCase::randomBoolean))));
156157
mutators.add(() -> mutation
157158
.scroll(randomValueOtherThan(searchRequest.scroll(), () -> new Scroll(new TimeValue(randomNonNegativeLong() % 100000)))));
158159
mutators.add(() -> mutation.searchType(randomValueOtherThan(searchRequest.searchType(),
@@ -162,20 +163,7 @@ private SearchRequest mutate(SearchRequest searchRequest) throws IOException {
162163
return mutation;
163164
}
164165

165-
private static SearchRequest copyRequest(SearchRequest searchRequest) throws IOException {
166-
SearchRequest result = new SearchRequest();
167-
result.indices(searchRequest.indices());
168-
result.indicesOptions(searchRequest.indicesOptions());
169-
result.types(searchRequest.types());
170-
result.searchType(searchRequest.searchType());
171-
result.preference(searchRequest.preference());
172-
result.routing(searchRequest.routing());
173-
result.requestCache(searchRequest.requestCache());
174-
result.allowPartialSearchResults(searchRequest.allowPartialSearchResults());
175-
result.scroll(searchRequest.scroll());
176-
if (searchRequest.source() != null) {
177-
result.source(searchRequest.source());
178-
}
179-
return result;
166+
private static SearchRequest copyRequest(SearchRequest searchRequest) {
167+
return new SearchRequest(searchRequest);
180168
}
181169
}

0 commit comments

Comments
 (0)