Skip to content

Commit 748dfb0

Browse files
committed
Adding basic search request documentation for high level client (#25651)
1 parent 833c8a4 commit 748dfb0

File tree

3 files changed

+314
-2
lines changed

3 files changed

+314
-2
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,28 @@
2828
import org.elasticsearch.action.search.SearchRequest;
2929
import org.elasticsearch.action.search.SearchResponse;
3030
import org.elasticsearch.action.search.SearchScrollRequest;
31+
import org.elasticsearch.action.search.ShardSearchFailure;
32+
import org.elasticsearch.action.support.IndicesOptions;
3133
import org.elasticsearch.action.support.WriteRequest;
3234
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
3335
import org.elasticsearch.client.RestHighLevelClient;
3436
import org.elasticsearch.common.unit.TimeValue;
3537
import org.elasticsearch.common.xcontent.XContentType;
38+
import org.elasticsearch.index.query.QueryBuilders;
3639
import org.elasticsearch.rest.RestStatus;
3740
import org.elasticsearch.search.Scroll;
3841
import org.elasticsearch.search.SearchHit;
3942
import org.elasticsearch.search.SearchHits;
4043
import org.elasticsearch.search.builder.SearchSourceBuilder;
44+
import org.elasticsearch.search.sort.ScoreSortBuilder;
45+
import org.elasticsearch.search.sort.SortOrder;
4146

4247
import java.io.IOException;
48+
import java.util.Arrays;
4349
import java.util.Collections;
4450
import java.util.List;
51+
import java.util.Map;
52+
import java.util.concurrent.TimeUnit;
4553

4654
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
4755
import static org.hamcrest.Matchers.greaterThan;
@@ -63,6 +71,134 @@
6371
*/
6472
public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
6573

74+
@SuppressWarnings({ "unused", "unchecked" })
75+
public void testSearch() throws IOException {
76+
RestHighLevelClient client = highLevelClient();
77+
{
78+
BulkRequest request = new BulkRequest();
79+
request.add(new IndexRequest("posts", "doc", "1")
80+
.source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?", "user",
81+
Arrays.asList("kimchy", "luca"), "innerObject", Collections.singletonMap("key", "value")));
82+
request.add(new IndexRequest("posts", "doc", "2")
83+
.source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch", "user",
84+
Arrays.asList("kimchy", "christoph"), "innerObject", Collections.singletonMap("key", "value")));
85+
request.add(new IndexRequest("posts", "doc", "3")
86+
.source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch", "user",
87+
Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
88+
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
89+
BulkResponse bulkResponse = client.bulk(request);
90+
assertSame(bulkResponse.status(), RestStatus.OK);
91+
assertFalse(bulkResponse.hasFailures());
92+
}
93+
{
94+
// tag::search-request-basic
95+
SearchRequest searchRequest = new SearchRequest(); // <1>
96+
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // <2>
97+
searchSourceBuilder.query(QueryBuilders.matchAllQuery()); // <3>
98+
// end::search-request-basic
99+
}
100+
{
101+
// tag::search-request-indices-types
102+
SearchRequest searchRequest = new SearchRequest("posts");
103+
searchRequest.types("doc");
104+
// end::search-request-indices-types
105+
// tag::search-request-routing
106+
searchRequest.routing("routing"); // <1>
107+
// end::search-request-routing
108+
// tag::search-request-indicesOptions
109+
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1>
110+
// end::search-request-indicesOptions
111+
// tag::search-request-preference
112+
searchRequest.preference("_local"); // <1>
113+
// end::search-request-preference
114+
assertNotNull(client.search(searchRequest));
115+
}
116+
{
117+
// tag::search-source-basics
118+
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // <1>
119+
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); // <2>
120+
sourceBuilder.from(0); // <3>
121+
sourceBuilder.size(5); // <4>
122+
sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.ASC));
123+
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // <5>
124+
// end::search-source-basics
125+
126+
// tag::search-source-setter
127+
SearchRequest searchRequest = new SearchRequest();
128+
searchRequest.source(sourceBuilder);
129+
// end::search-source-setter
130+
131+
// tag::search-execute
132+
SearchResponse searchResponse = client.search(searchRequest);
133+
// end::search-execute
134+
135+
// tag::search-execute-async
136+
client.searchAsync(searchRequest, new ActionListener<SearchResponse>() {
137+
@Override
138+
public void onResponse(SearchResponse searchResponse) {
139+
// <1>
140+
}
141+
142+
@Override
143+
public void onFailure(Exception e) {
144+
// <2>
145+
}
146+
});
147+
// end::search-execute-async
148+
149+
// tag::search-response-1
150+
RestStatus status = searchResponse.status();
151+
TimeValue took = searchResponse.getTook();
152+
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
153+
boolean timedOut = searchResponse.isTimedOut();
154+
// end::search-response-1
155+
156+
// tag::search-response-2
157+
int totalShards = searchResponse.getTotalShards();
158+
int successfulShards = searchResponse.getSuccessfulShards();
159+
int failedShards = searchResponse.getFailedShards();
160+
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
161+
// failures should be handled here
162+
}
163+
// end::search-response-2
164+
assertNotNull(searchResponse);
165+
166+
// tag::search-hits-get
167+
SearchHits hits = searchResponse.getHits();
168+
// end::search-hits-get
169+
// tag::search-hits-info
170+
long totalHits = hits.getTotalHits();
171+
float maxScore = hits.getMaxScore();
172+
// end::search-hits-info
173+
// tag::search-hits-singleHit
174+
SearchHit[] searchHits = hits.getHits();
175+
for (SearchHit hit : searchHits) {
176+
// do something with the SearchHit
177+
}
178+
// end::search-hits-singleHit
179+
for (SearchHit hit : searchHits) {
180+
// tag::search-hits-singleHit-properties
181+
String index = hit.getIndex();
182+
String type = hit.getType();
183+
String id = hit.getId();
184+
float score = hit.getScore();
185+
// end::search-hits-singleHit-properties
186+
// tag::search-hits-singleHit-source
187+
String sourceAsString = hit.getSourceAsString();
188+
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
189+
String documentTitle = (String) sourceAsMap.get("title");
190+
List<Object> users = (List<Object>) sourceAsMap.get("user");
191+
Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
192+
// end::search-hits-singleHit-source
193+
}
194+
assertEquals(3, totalHits);
195+
assertNotNull(hits.getHits()[0].getSourceAsString());
196+
assertNotNull(hits.getHits()[0].getSourceAsMap().get("title"));
197+
assertNotNull(hits.getHits()[0].getSourceAsMap().get("user"));
198+
assertNotNull(hits.getHits()[0].getSourceAsMap().get("innerObject"));
199+
}
200+
}
201+
66202
public void testScroll() throws IOException {
67203
RestHighLevelClient client = highLevelClient();
68204
{

core/src/main/java/org/elasticsearch/search/SearchHit.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public SearchHit sourceRef(BytesReference source) {
255255
}
256256

257257
/**
258-
* Returns bytes reference, also un compress the source if needed.
258+
* Returns bytes reference, also uncompress the source if needed.
259259
*/
260260
public BytesReference getSourceRef() {
261261
if (this.source == null) {
Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,180 @@
11
[[java-rest-high-search]]
22
=== Search API
33

4-
To be documented.
4+
[[java-rest-high-document-search-request]]
5+
==== Search Request
6+
7+
The `SearchRequest` is used for any operation that has to do with searching
8+
documents, aggregations, suggestions and also offers ways of requesting
9+
highlighting on the resulting documents.
10+
11+
In its most basic form, a query can be added to the request like this:
12+
13+
["source","java",subs="attributes,callouts,macros"]
14+
--------------------------------------------------
15+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-basic]
16+
--------------------------------------------------
17+
18+
<1> Creates the `SeachRequest`. Without arguments this runs against all indices.
19+
<2> Most parameters of the search can be added to the `SearchSourceBuilder`
20+
which contains everything that
21+
in the Rest API would be placed in the search request body.
22+
<3> Add a `match_all` query to the `SearchSourceBuilder`.
23+
24+
==== Optional arguments
25+
26+
Lets first look at some of the optional argument of a `SearchRequest`.
27+
First of all, the request can be restricted to one or more indices using the
28+
constructor or to on or more types using a setter:
29+
30+
["source","java",subs="attributes,callouts,macros"]
31+
--------------------------------------------------
32+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-indices-types]
33+
--------------------------------------------------
34+
35+
There are a couple of other interesting optional parameters:
36+
37+
["source","java",subs="attributes,callouts,macros"]
38+
--------------------------------------------------
39+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-routing]
40+
--------------------------------------------------
41+
<1> Set a routing parameter
42+
43+
["source","java",subs="attributes,callouts,macros"]
44+
--------------------------------------------------
45+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-indicesOptions]
46+
--------------------------------------------------
47+
<1> Setting `IndicesOptions` controls how unavailable indices are resolved and
48+
how wildcard expressions are expanded
49+
50+
["source","java",subs="attributes,callouts,macros"]
51+
--------------------------------------------------
52+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-preference]
53+
--------------------------------------------------
54+
<1> Use the preference parameter e.g. to execute the search to prefer local
55+
shards. The The default is to randomize across shards.
56+
57+
==== Using the SearchSourceBuilder
58+
59+
Most options controlling the search behavior can be set on the
60+
`SearchSourceBuilder`,
61+
which contains more or less the equivalent of the options in the search request
62+
body of the Rest API.
63+
64+
Here are a few examples of some common options:
65+
66+
["source","java",subs="attributes,callouts,macros"]
67+
--------------------------------------------------
68+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-basics]
69+
--------------------------------------------------
70+
<1> Create a `SearchSourceBuilder` with default options.
71+
<2> Set the query. Can be any type of `QueryBuilder`
72+
<3> Set the `from` option that determines the result index to start searching
73+
from. Defaults to 0.
74+
<4> Set the `size` option that determines the number of search hits to return.
75+
Defaults to 10.
76+
<5> Set an optional timeout that controls how long the search is allowed to
77+
take.
78+
79+
After this, the `SearchSourceBuilder` only needs to be added to the
80+
`SearchRequest`:
81+
82+
["source","java",subs="attributes,callouts,macros"]
83+
--------------------------------------------------
84+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-setter]
85+
--------------------------------------------------
86+
87+
88+
[[java-rest-high-document-search-sync]]
89+
==== Synchronous Execution
90+
91+
When executing a `SearchRequest` in the following manner, the client waits
92+
for the `SearchResponse` to be returned before continuing with code execution:
93+
94+
["source","java",subs="attributes,callouts,macros"]
95+
--------------------------------------------------
96+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute]
97+
--------------------------------------------------
98+
99+
[[java-rest-high-document-search-async]]
100+
==== Asynchronous Execution
101+
102+
103+
Executing a `SearchRequest` can also be done in an asynchronous fashion so that
104+
the client can return directly. Users need to specify how the response or
105+
potential failures will be handled by passing in appropriate listeners:
106+
107+
["source","java",subs="attributes,callouts,macros"]
108+
--------------------------------------------------
109+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute-async]
110+
--------------------------------------------------
111+
<1> Called when the execution is successfully completed.
112+
<2> Called when the whole `SearchRequest` fails.
113+
114+
==== SearchResponse
115+
116+
The `SearchResponse` that is returned by executing the search provides details
117+
about the search execution itself as well as access to the documents returned.
118+
First, there is useful information about the request execution itself, like the
119+
HTTP status code, execution time or wether the request terminated early or timed
120+
out:
121+
122+
["source","java",subs="attributes,callouts,macros"]
123+
--------------------------------------------------
124+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-response-1]
125+
--------------------------------------------------
126+
127+
Second, the response also provides information about the execution on the
128+
shard level by offering statistics about the total number of shards that were
129+
affected by the search, and the successful vs. unsuccessful shards. Possible
130+
failures can also be handled by iterating over an array off
131+
`ShardSearchFailures` like in the following example:
132+
133+
["source","java",subs="attributes,callouts,macros"]
134+
--------------------------------------------------
135+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-response-2]
136+
--------------------------------------------------
137+
138+
To get access to the returned documents, we need to first get the `SearchHits`
139+
contained in the response:
140+
141+
["source","java",subs="attributes,callouts,macros"]
142+
--------------------------------------------------
143+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-get]
144+
--------------------------------------------------
145+
146+
The `SearchHits` provides global information about all hits, like total number
147+
of hits or the maximum score:
148+
149+
["source","java",subs="attributes,callouts,macros"]
150+
--------------------------------------------------
151+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-info]
152+
--------------------------------------------------
153+
154+
Nested inside the `SearchHits` are the individual search results that can
155+
be iterated over like this:
156+
157+
158+
["source","java",subs="attributes,callouts,macros"]
159+
--------------------------------------------------
160+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit]
161+
--------------------------------------------------
162+
163+
The `SearchHit` provides access to basic information like index, type, docId and
164+
score of each search hit:
165+
166+
["source","java",subs="attributes,callouts,macros"]
167+
--------------------------------------------------
168+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit-properties]
169+
--------------------------------------------------
170+
171+
Furthermore, it lets you get back the document source, either as a simple
172+
JSON-String or as a map of key/value pairs. In this map, regular fields
173+
are keyed by the field name and contain the field value. Multi-valued fields are
174+
returned as lists of objects, nested objects as another key/value map. These
175+
cases need to be case accordingly:
176+
177+
["source","java",subs="attributes,callouts,macros"]
178+
--------------------------------------------------
179+
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit-source]
180+
--------------------------------------------------

0 commit comments

Comments
 (0)