Docs: HighLevelRestClient#multiSearch (#29144)
Adds docs for `HighLevelRestClient#multiSearch`. Unlike the `multiGet` docs these are much more sparse because multi-search doesn't support setting many options on the `MultiSearchRequest` and instead just wraps a list of `SearchRequest`s. Closes #28389
This commit is contained in:
parent
fede633563
commit
8c59e43ac7
|
@ -27,6 +27,8 @@ import org.elasticsearch.action.index.IndexRequest;
|
|||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.search.ClearScrollRequest;
|
||||
import org.elasticsearch.action.search.ClearScrollResponse;
|
||||
import org.elasticsearch.action.search.MultiSearchRequest;
|
||||
import org.elasticsearch.action.search.MultiSearchResponse;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.search.SearchScrollRequest;
|
||||
|
@ -85,45 +87,15 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
/**
|
||||
* This class is used to generate the Java High Level REST Client Search API documentation.
|
||||
* <p>
|
||||
* You need to wrap your code between two tags like:
|
||||
* // tag::example
|
||||
* // end::example
|
||||
* <p>
|
||||
* Where example is your tag name.
|
||||
* <p>
|
||||
* Then in the documentation, you can extract what is between tag and end tags with
|
||||
* ["source","java",subs="attributes,callouts,macros"]
|
||||
* --------------------------------------------------
|
||||
* include-tagged::{doc-tests}/SearchDocumentationIT.java[example]
|
||||
* --------------------------------------------------
|
||||
* <p>
|
||||
* The column width of the code block is 84. If the code contains a line longer
|
||||
* than 84, the line will be cut and a horizontal scroll bar will be displayed.
|
||||
* (the code indentation of the tag is not included in the width)
|
||||
* Documentation for search APIs in the high level java client.
|
||||
* Code wrapped in {@code tag} and {@code end} tags is included in the docs.
|
||||
*/
|
||||
public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
||||
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public void testSearch() throws Exception {
|
||||
indexSearchTestData();
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
{
|
||||
BulkRequest request = new BulkRequest();
|
||||
request.add(new IndexRequest("posts", "doc", "1")
|
||||
.source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?", "user",
|
||||
Arrays.asList("kimchy", "luca"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.add(new IndexRequest("posts", "doc", "2")
|
||||
.source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch", "user",
|
||||
Arrays.asList("kimchy", "christoph"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.add(new IndexRequest("posts", "doc", "3")
|
||||
.source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch", "user",
|
||||
Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = client.bulk(request);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
{
|
||||
// tag::search-request-basic
|
||||
SearchRequest searchRequest = new SearchRequest(); // <1>
|
||||
|
@ -715,4 +687,90 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
assertTrue(succeeded);
|
||||
}
|
||||
}
|
||||
|
||||
public void testMultiSearch() throws Exception {
|
||||
indexSearchTestData();
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
{
|
||||
// tag::multi-search-request-basic
|
||||
MultiSearchRequest request = new MultiSearchRequest(); // <1>
|
||||
SearchRequest firstSearchRequest = new SearchRequest(); // <2>
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery("user", "kimchy"));
|
||||
firstSearchRequest.source(searchSourceBuilder);
|
||||
request.add(firstSearchRequest); // <3>
|
||||
SearchRequest secondSearchRequest = new SearchRequest(); // <4>
|
||||
searchSourceBuilder = new SearchSourceBuilder();
|
||||
searchSourceBuilder.query(QueryBuilders.matchQuery("user", "luca"));
|
||||
secondSearchRequest.source(searchSourceBuilder);
|
||||
request.add(secondSearchRequest);
|
||||
// end::multi-search-request-basic
|
||||
// tag::multi-search-execute
|
||||
MultiSearchResponse response = client.multiSearch(request);
|
||||
// end::multi-search-execute
|
||||
// tag::multi-search-response
|
||||
MultiSearchResponse.Item firstResponse = response.getResponses()[0]; // <1>
|
||||
assertNull(firstResponse.getFailure()); // <2>
|
||||
SearchResponse searchResponse = firstResponse.getResponse(); // <3>
|
||||
assertEquals(3, searchResponse.getHits().getTotalHits());
|
||||
MultiSearchResponse.Item secondResponse = response.getResponses()[1]; // <4>
|
||||
assertNull(secondResponse.getFailure());
|
||||
searchResponse = secondResponse.getResponse();
|
||||
assertEquals(1, searchResponse.getHits().getTotalHits());
|
||||
// end::multi-search-response
|
||||
|
||||
// tag::multi-search-execute-listener
|
||||
ActionListener<MultiSearchResponse> listener = new ActionListener<MultiSearchResponse>() {
|
||||
@Override
|
||||
public void onResponse(MultiSearchResponse response) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::multi-search-execute-listener
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
// tag::multi-search-execute-async
|
||||
client.multiSearchAsync(request, listener); // <1>
|
||||
// end::multi-search-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
{
|
||||
// tag::multi-search-request-index
|
||||
MultiSearchRequest request = new MultiSearchRequest();
|
||||
request.add(new SearchRequest("posts") // <1>
|
||||
.types("doc")); // <2>
|
||||
// end::multi-search-request-index
|
||||
MultiSearchResponse response = client.multiSearch(request);
|
||||
MultiSearchResponse.Item firstResponse = response.getResponses()[0];
|
||||
assertNull(firstResponse.getFailure());
|
||||
SearchResponse searchResponse = firstResponse.getResponse();
|
||||
assertEquals(3, searchResponse.getHits().getTotalHits());
|
||||
}
|
||||
}
|
||||
|
||||
private void indexSearchTestData() throws IOException {
|
||||
BulkRequest request = new BulkRequest();
|
||||
request.add(new IndexRequest("posts", "doc", "1")
|
||||
.source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?", "user",
|
||||
Arrays.asList("kimchy", "luca"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.add(new IndexRequest("posts", "doc", "2")
|
||||
.source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch", "user",
|
||||
Arrays.asList("kimchy", "christoph"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.add(new IndexRequest("posts", "doc", "3")
|
||||
.source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch", "user",
|
||||
Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
BulkResponse bulkResponse = highLevelClient().bulk(request);
|
||||
assertSame(RestStatus.OK, bulkResponse.status());
|
||||
assertFalse(bulkResponse.hasFailures());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
[[java-rest-high-multi-search]]
|
||||
=== Multi-Search API
|
||||
|
||||
The `multiSearch` API executes multiple <<java-rest-high-search,`search`>>
|
||||
requests in a single http request in parallel.
|
||||
|
||||
[[java-rest-high-multi-search-request]]
|
||||
==== Multi-Search Request
|
||||
|
||||
The `MultiSearchRequest` is built empty and you add all of the searches that
|
||||
you wish to execute to it:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[multi-search-request-basic]
|
||||
--------------------------------------------------
|
||||
<1> Create an empty `MultiSearchRequest`.
|
||||
<2> Create an empty `SearchRequest` and populate it just like you
|
||||
would for a regular <<java-rest-high-search,`search`>>.
|
||||
<3> Add the `SearchRequest` to the `MultiSearchRequest`.
|
||||
<4> Build a second `SearchRequest` and add it to the `MultiSearchRequest`.
|
||||
|
||||
===== Optional arguments
|
||||
|
||||
The `SearchRequest`s inside of `MultiSearchRequest` support all of
|
||||
<<java-rest-high-search-request-optional,`search`>>'s optional arguments.
|
||||
For example:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-indices-types]
|
||||
--------------------------------------------------
|
||||
<1> Restricts the request to an index
|
||||
<2> Limits the request to a type
|
||||
|
||||
[[java-rest-high-multi-search-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
The `multiSearch` method executes `MultiSearchRequest`s synchronously:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[multi-search-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-multi-search-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The `multiSearchAsync` method executes `MultiSearchRequest`s asynchronously,
|
||||
calling the provided `ActionListener` when the response is ready.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `MultiSearchRequest` to execute and the `ActionListener` to use when
|
||||
the execution completes
|
||||
|
||||
The asynchronous method does not block and returns immediately. Once it is
|
||||
completed the `ActionListener` is called back using the `onResponse` method
|
||||
if the execution successfully completed or using the `onFailure` method if
|
||||
it failed.
|
||||
|
||||
A typical listener for `MultiSearchResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[multi-search-execute-listener]
|
||||
--------------------------------------------------
|
||||
<1> Called when the execution is successfully completed.
|
||||
<2> Called when the whole `SearchRequest` fails.
|
||||
|
||||
==== MultiSearchResponse
|
||||
|
||||
The `MultiSearchResponse` that is returned by executing the `multiSearch`
|
||||
a `MultiSearchResponse.Item` for each `SearchRequest` in the
|
||||
`MultiSearchRequest`. Each `MultiSearchResponse.Item` contains an
|
||||
exception in `getFailure` if the request failed or a
|
||||
<<java-rest-high-search-response,`SearchResponse`>> in `getResponse` if
|
||||
the request succeeded:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/SearchDocumentationIT.java[multi-search-response]
|
||||
--------------------------------------------------
|
||||
<1> The item for the first search.
|
||||
<2> It succeeded so `getFailure` returns null.
|
||||
<3> And there is a <<java-rest-high-search-response,`SearchResponse`>> in
|
||||
`getResponse`.
|
||||
<4> The item for the second search.
|
|
@ -20,6 +20,7 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-basic]
|
|||
<3> Add a `match_all` query to the `SearchSourceBuilder`.
|
||||
<4> Add the `SearchSourceBuilder` to the `SeachRequest`.
|
||||
|
||||
[[java-rest-high-search-request-optional]]
|
||||
===== Optional arguments
|
||||
|
||||
Let's first look at some of the optional arguments of a `SearchRequest`:
|
||||
|
@ -140,7 +141,7 @@ The `SearchSourceBuilder` allows to add one or more `SortBuilder` instances. The
|
|||
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-sorting]
|
||||
--------------------------------------------------
|
||||
<1> Sort descending by `_score` (the default)
|
||||
<2> Also sort ascending by `_id` field
|
||||
<2> Also sort ascending by `_id` field
|
||||
|
||||
===== Source filtering
|
||||
|
||||
|
@ -268,6 +269,7 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute-listener]
|
|||
<1> Called when the execution is successfully completed.
|
||||
<2> Called when the whole `SearchRequest` fails.
|
||||
|
||||
[[java-rest-high-search-response]]
|
||||
==== SearchResponse
|
||||
|
||||
The `SearchResponse` that is returned by executing the search provides details
|
||||
|
|
|
@ -31,9 +31,11 @@ The Java High Level REST Client supports the following Search APIs:
|
|||
* <<java-rest-high-search>>
|
||||
* <<java-rest-high-search-scroll>>
|
||||
* <<java-rest-high-clear-scroll>>
|
||||
* <<java-rest-high-multi-search>>
|
||||
|
||||
include::search/search.asciidoc[]
|
||||
include::search/scroll.asciidoc[]
|
||||
include::search/multi-search.asciidoc[]
|
||||
|
||||
== Miscellaneous APIs
|
||||
|
||||
|
|
Loading…
Reference in New Issue