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.index.IndexResponse;
|
||||||
import org.elasticsearch.action.search.ClearScrollRequest;
|
import org.elasticsearch.action.search.ClearScrollRequest;
|
||||||
import org.elasticsearch.action.search.ClearScrollResponse;
|
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.SearchRequest;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.action.search.SearchScrollRequest;
|
import org.elasticsearch.action.search.SearchScrollRequest;
|
||||||
|
@ -85,45 +87,15 @@ import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to generate the Java High Level REST Client Search API documentation.
|
* Documentation for search APIs in the high level java client.
|
||||||
* <p>
|
* Code wrapped in {@code tag} and {@code end} tags is included in the docs.
|
||||||
* 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)
|
|
||||||
*/
|
*/
|
||||||
public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "unchecked"})
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
public void testSearch() throws Exception {
|
public void testSearch() throws Exception {
|
||||||
|
indexSearchTestData();
|
||||||
RestHighLevelClient client = highLevelClient();
|
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
|
// tag::search-request-basic
|
||||||
SearchRequest searchRequest = new SearchRequest(); // <1>
|
SearchRequest searchRequest = new SearchRequest(); // <1>
|
||||||
|
@ -715,4 +687,90 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
|
||||||
assertTrue(succeeded);
|
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`.
|
<3> Add a `match_all` query to the `SearchSourceBuilder`.
|
||||||
<4> Add the `SearchSourceBuilder` to the `SeachRequest`.
|
<4> Add the `SearchSourceBuilder` to the `SeachRequest`.
|
||||||
|
|
||||||
|
[[java-rest-high-search-request-optional]]
|
||||||
===== Optional arguments
|
===== Optional arguments
|
||||||
|
|
||||||
Let's first look at some of the optional arguments of a `SearchRequest`:
|
Let's first look at some of the optional arguments of a `SearchRequest`:
|
||||||
|
@ -268,6 +269,7 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-execute-listener]
|
||||||
<1> Called when the execution is successfully completed.
|
<1> Called when the execution is successfully completed.
|
||||||
<2> Called when the whole `SearchRequest` fails.
|
<2> Called when the whole `SearchRequest` fails.
|
||||||
|
|
||||||
|
[[java-rest-high-search-response]]
|
||||||
==== SearchResponse
|
==== SearchResponse
|
||||||
|
|
||||||
The `SearchResponse` that is returned by executing the search provides details
|
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>>
|
||||||
* <<java-rest-high-search-scroll>>
|
* <<java-rest-high-search-scroll>>
|
||||||
* <<java-rest-high-clear-scroll>>
|
* <<java-rest-high-clear-scroll>>
|
||||||
|
* <<java-rest-high-multi-search>>
|
||||||
|
|
||||||
include::search/search.asciidoc[]
|
include::search/search.asciidoc[]
|
||||||
include::search/scroll.asciidoc[]
|
include::search/scroll.asciidoc[]
|
||||||
|
include::search/multi-search.asciidoc[]
|
||||||
|
|
||||||
== Miscellaneous APIs
|
== Miscellaneous APIs
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue