Skip to content

Commit eb3e82e

Browse files
committed
Add rest_total_hits_as_int in the search APIs
This change adds the support for a search query parameter named `rest_total_hits_as_int`. This parameter will be used in the next major version (7.0) to restore the total hits as a number in the response. This param is added in this version (6.x) to handle mixed cluster queries where nodes are in multiple versions (7.0 and 6.latest). The param does not change anything in 6x since total hits is always a number in 6x so it is just ignored.
1 parent c011a1f commit eb3e82e

File tree

17 files changed

+277
-4
lines changed

17 files changed

+277
-4
lines changed

modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestMultiSearchTemplateAction.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,24 @@
2929
import org.elasticsearch.rest.action.search.RestSearchAction;
3030

3131
import java.io.IOException;
32+
import java.util.Arrays;
3233
import java.util.Collections;
34+
import java.util.HashSet;
3335
import java.util.Set;
3436

3537
import static org.elasticsearch.rest.RestRequest.Method.GET;
3638
import static org.elasticsearch.rest.RestRequest.Method.POST;
3739

3840
public class RestMultiSearchTemplateAction extends BaseRestHandler {
3941

40-
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
42+
private static final Set<String> RESPONSE_PARAMS;
43+
44+
static {
45+
final Set<String> responseParams = new HashSet<>(
46+
Arrays.asList(RestSearchAction.TYPED_KEYS_PARAM, RestSearchAction.TOTAL_HIT_AS_INT_PARAM)
47+
);
48+
RESPONSE_PARAMS = Collections.unmodifiableSet(responseParams);
49+
}
4150

4251
private final boolean allowExplicitIndex;
4352

modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,24 @@
3030
import org.elasticsearch.rest.action.search.RestSearchAction;
3131

3232
import java.io.IOException;
33+
import java.util.Arrays;
3334
import java.util.Collections;
35+
import java.util.HashSet;
3436
import java.util.Set;
3537

3638
import static org.elasticsearch.rest.RestRequest.Method.GET;
3739
import static org.elasticsearch.rest.RestRequest.Method.POST;
3840

3941
public class RestSearchTemplateAction extends BaseRestHandler {
4042

41-
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
43+
private static final Set<String> RESPONSE_PARAMS;
44+
45+
static {
46+
final Set<String> responseParams = new HashSet<>(
47+
Arrays.asList(RestSearchAction.TYPED_KEYS_PARAM, RestSearchAction.TOTAL_HIT_AS_INT_PARAM)
48+
);
49+
RESPONSE_PARAMS = Collections.unmodifiableSet(responseParams);
50+
}
4251

4352
public RestSearchTemplateAction(Settings settings, RestController controller) {
4453
super(settings);

modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/30_search_template.yml

+27
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,30 @@
124124
- match: { hits.total: 1 }
125125
- length: { hits.hits: 1 }
126126
- length: { profile: 1 }
127+
128+
---
129+
"Test with rest_total_hits_as_int":
130+
- skip:
131+
version: " - 6.5.99"
132+
reason: rest_total_hits_as_int was introduced in 6.6.0
133+
134+
- do:
135+
index:
136+
index: test
137+
type: type
138+
id: 1
139+
body: {}
140+
141+
- do:
142+
put_script:
143+
id: "template_1"
144+
body: { "script": { "lang": "mustache", "source": { "query": { "match_all": {} } } } }
145+
146+
- match: { acknowledged: true }
147+
148+
- do:
149+
search_template:
150+
rest_total_hits_as_int: true
151+
body: { "id": "template_1", "params": {} }
152+
153+
- match: { hits.total: 0 }

modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/50_multi_search_template.yml

+44
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,47 @@ setup:
156156
- match: { responses.0.hits.total: 2 }
157157
- match: { responses.1.hits.total: 1 }
158158
- match: { responses.2.hits.total: 1 }
159+
160+
161+
- do:
162+
put_script:
163+
id: stored_template_1
164+
body: { "script": { "lang" : "mustache", "source": { "query": {"match": {"{{field}}": "{{value}}" }}}}}
165+
- match: { acknowledged: true }
166+
167+
---
168+
"Test with rest_total_hits_as_int":
169+
- skip:
170+
version: " - 6.5.99"
171+
reason: rest_total_hits_as_int was introduced in 6.6.0
172+
173+
- do:
174+
put_script:
175+
id: stored_template_1
176+
body: { "script": { "lang": "mustache", "source": { "query": {"match": {"{{field}}": "{{value}}" }}}}}
177+
- match: { acknowledged: true }
178+
179+
- do:
180+
msearch_template:
181+
rest_total_hits_as_int: true
182+
body:
183+
- index: index_*
184+
- id: stored_template_1
185+
params:
186+
field: "foo"
187+
value: "foo"
188+
- index: _all
189+
- id: stored_template_1
190+
params:
191+
field: "foo"
192+
value: "bar"
193+
- index: index_2
194+
- id: stored_template_1
195+
params:
196+
field: "foo"
197+
value: "foo"
198+
199+
- match: { responses.0.hits.total: 2 }
200+
- match: { responses.1.hits.total: 1 }
201+
- match: { responses.2.hits.total: 1 }
202+

rest-api-spec/src/main/resources/rest-api-spec/api/msearch.json

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
"type" : "number",
3939
"description" : "The number of concurrent shard requests each sub search executes concurrently. This value should be used to limit the impact of the search on the cluster in order to limit the number of concurrent shard requests",
4040
"default" : "The default grows with the number of nodes in the cluster but is at most 256."
41+
},
42+
"rest_total_hits_as_int" : {
43+
"type" : "boolean",
44+
"description" : "This parameter is ignored in this version. It is used in the next major version to control whether the rest response should render the total.hits as an object or a number",
45+
"default" : false
4146
}
4247
}
4348
},

rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
"max_concurrent_searches" : {
2929
"type" : "number",
3030
"description" : "Controls the maximum number of concurrent searches the multi search api will execute"
31+
},
32+
"rest_total_hits_as_int" : {
33+
"type" : "boolean",
34+
"description" : "This parameter is ignored in this version. It is used in the next major version to control whether the rest response should render the total.hits as an object or a number",
35+
"default" : false
3136
}
3237
}
3338
},

rest-api-spec/src/main/resources/rest-api-spec/api/scroll.json

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
"scroll_id": {
2020
"type" : "string",
2121
"description" : "The scroll ID for scrolled search"
22+
},
23+
"rest_total_hits_as_int" : {
24+
"type" : "boolean",
25+
"description" : "This parameter is ignored in this version. It is used in the next major version to control whether the rest response should render the total.hits as an object or a number",
26+
"default" : false
2227
}
2328
}
2429
},

rest-api-spec/src/main/resources/rest-api-spec/api/search.json

+5
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@
182182
"type" : "number",
183183
"description" : "A threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting if the number of shards the search request expands to exceeds the threshold. This filter roundtrip can limit the number of shards significantly if for instance a shard can not match any documents based on it's rewrite method ie. if date filters are mandatory to match but the shard bounds and the query are disjoint.",
184184
"default" : 128
185+
},
186+
"rest_total_hits_as_int" : {
187+
"type" : "boolean",
188+
"description" : "This parameter is ignored in this version. It is used in the next major version to control whether the rest response should render the total.hits as an object or a number",
189+
"default" : false
185190
}
186191
}
187192
},

rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@
6262
"typed_keys": {
6363
"type" : "boolean",
6464
"description" : "Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
65+
},
66+
"rest_total_hits_as_int" : {
67+
"type" : "boolean",
68+
"description" : "This parameter is ignored in this version. It is used in the next major version to control whether the rest response should render the total.hits as an object or a number",
69+
"default" : false
6570
}
6671
}
6772
},

rest-api-spec/src/main/resources/rest-api-spec/test/msearch/10_basic.yml

+25
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,28 @@ setup:
9696
- match: { responses.3.error.root_cause.0.reason: "/no.such.index/" }
9797
- match: { responses.3.error.root_cause.0.index: index_3 }
9898
- match: { responses.4.hits.total: 4 }
99+
100+
---
101+
"Search with rest_total_hits_as_int":
102+
- skip:
103+
version: " - 6.5.99"
104+
reason: rest_total_hits_as_int was introduced in 6.6.0
105+
106+
- do:
107+
msearch:
108+
rest_total_hits_as_int: true
109+
body:
110+
- index: index_*
111+
- query:
112+
match: {foo: foo}
113+
- index: index_2
114+
- query:
115+
match_all: {}
116+
- index: index_1
117+
- query:
118+
match: {foo: foo}
119+
120+
- match: { responses.0.hits.total: 2 }
121+
- match: { responses.1.hits.total: 1 }
122+
- match: { responses.2.hits.total: 1 }
123+

rest-api-spec/src/main/resources/rest-api-spec/test/scroll/10_basic.yml

+63
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,66 @@
236236
query:
237237
match_all: {}
238238
size: 0
239+
240+
---
241+
"Scroll with rest_total_as_int":
242+
- skip:
243+
version: " - 6.5.99"
244+
reason: rest_total_hits_as_int was introduced in 6.6.0
245+
- do:
246+
indices.create:
247+
index: test_scroll
248+
- do:
249+
index:
250+
index: test_scroll
251+
type: test
252+
id: 42
253+
body: { foo: 1 }
254+
255+
- do:
256+
index:
257+
index: test_scroll
258+
type: test
259+
id: 43
260+
body: { foo: 2 }
261+
262+
- do:
263+
indices.refresh: {}
264+
265+
- do:
266+
search:
267+
index: test_scroll
268+
size: 1
269+
scroll: 1m
270+
sort: foo
271+
rest_total_hits_as_int: true
272+
body:
273+
query:
274+
match_all: {}
275+
276+
- set: {_scroll_id: scroll_id}
277+
- match: {hits.total: 2 }
278+
- length: {hits.hits: 1 }
279+
- match: {hits.hits.0._id: "42" }
280+
281+
- do:
282+
scroll:
283+
rest_total_hits_as_int: true
284+
body: { "scroll_id": "$scroll_id", "scroll": "1m"}
285+
286+
- match: {hits.total: 2 }
287+
- length: {hits.hits: 1 }
288+
- match: {hits.hits.0._id: "43" }
289+
290+
- do:
291+
scroll:
292+
rest_total_hits_as_int: true
293+
scroll_id: $scroll_id
294+
scroll: 1m
295+
296+
- match: {hits.total: 2 }
297+
- length: {hits.hits: 0 }
298+
299+
- do:
300+
clear_scroll:
301+
scroll_id: $scroll_id

rest-api-spec/src/main/resources/rest-api-spec/test/search/20_default_values.yml

+10
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,13 @@ setup:
7575
match:
7676
foo: bar
7777

78+
---
79+
"Search with rest_total_hits_as_int":
80+
- skip:
81+
version: " - 6.5.99"
82+
reason: rest_total_hits_as_int was introduced in 6.6.0
83+
- do:
84+
search:
85+
rest_total_hits_as_int: true
86+
87+
- match: {hits.total: 2}

server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
import org.elasticsearch.search.builder.SearchSourceBuilder;
3939

4040
import java.io.IOException;
41+
import java.util.Arrays;
4142
import java.util.Collections;
43+
import java.util.HashSet;
4244
import java.util.List;
4345
import java.util.Set;
4446

@@ -47,7 +49,14 @@
4749

4850
public class RestMultiSearchAction extends BaseRestHandler {
4951

50-
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
52+
private static final Set<String> RESPONSE_PARAMS;
53+
54+
static {
55+
final Set<String> responseParams = new HashSet<>(
56+
Arrays.asList(RestSearchAction.TYPED_KEYS_PARAM, RestSearchAction.TOTAL_HIT_AS_INT_PARAM)
57+
);
58+
RESPONSE_PARAMS = Collections.unmodifiableSet(responseParams);
59+
}
5160

5261
private final boolean allowExplicitIndex;
5362

server/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.io.IOException;
4444
import java.util.Arrays;
4545
import java.util.Collections;
46+
import java.util.HashSet;
4647
import java.util.Set;
4748
import java.util.function.IntConsumer;
4849

@@ -54,7 +55,13 @@
5455
public class RestSearchAction extends BaseRestHandler {
5556

5657
public static final String TYPED_KEYS_PARAM = "typed_keys";
57-
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(TYPED_KEYS_PARAM);
58+
public static final String TOTAL_HIT_AS_INT_PARAM = "rest_total_hits_as_int";
59+
private static final Set<String> RESPONSE_PARAMS;
60+
61+
static {
62+
final Set<String> responseParams = new HashSet<>(Arrays.asList(TYPED_KEYS_PARAM, TOTAL_HIT_AS_INT_PARAM));
63+
RESPONSE_PARAMS = Collections.unmodifiableSet(responseParams);
64+
}
5865

5966
public RestSearchAction(Settings settings, RestController controller) {
6067
super(settings);

server/src/main/java/org/elasticsearch/rest/action/search/RestSearchScrollAction.java

+9
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@
2929
import org.elasticsearch.search.Scroll;
3030

3131
import java.io.IOException;
32+
import java.util.Collections;
33+
import java.util.Set;
3234

3335
import static org.elasticsearch.common.unit.TimeValue.parseTimeValue;
3436
import static org.elasticsearch.rest.RestRequest.Method.GET;
3537
import static org.elasticsearch.rest.RestRequest.Method.POST;
3638

3739
public class RestSearchScrollAction extends BaseRestHandler {
40+
Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TOTAL_HIT_AS_INT_PARAM);
41+
3842
public RestSearchScrollAction(Settings settings, RestController controller) {
3943
super(settings);
4044

@@ -70,4 +74,9 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
7074
}});
7175
return channel -> client.searchScroll(searchScrollRequest, new RestStatusToXContentListener<>(channel));
7276
}
77+
78+
@Override
79+
protected Set<String> responseParams() {
80+
return RESPONSE_PARAMS;
81+
}
7382
}

0 commit comments

Comments
 (0)