diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java
index 22421dec6d9..96d962c3ac5 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java
@@ -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.
- *
- * You need to wrap your code between two tags like:
- * // tag::example
- * // end::example
- *
- * Where example is your tag name.
- *
- * 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]
- * --------------------------------------------------
- *
- * 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 listener = new ActionListener() {
+ @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());
+ }
}
diff --git a/docs/java-rest/high-level/search/multi-search.asciidoc b/docs/java-rest/high-level/search/multi-search.asciidoc
new file mode 100644
index 00000000000..1b76f897666
--- /dev/null
+++ b/docs/java-rest/high-level/search/multi-search.asciidoc
@@ -0,0 +1,90 @@
+[[java-rest-high-multi-search]]
+=== Multi-Search API
+
+The `multiSearch` API executes multiple <>
+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 <>.
+<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
+<>'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
+<> 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 <> in
+`getResponse`.
+<4> The item for the second search.
diff --git a/docs/java-rest/high-level/search/search.asciidoc b/docs/java-rest/high-level/search/search.asciidoc
index 2e8dda64286..af81775a900 100644
--- a/docs/java-rest/high-level/search/search.asciidoc
+++ b/docs/java-rest/high-level/search/search.asciidoc
@@ -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
diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc
index de5a3d6b6a6..0330b1903c5 100644
--- a/docs/java-rest/high-level/supported-apis.asciidoc
+++ b/docs/java-rest/high-level/supported-apis.asciidoc
@@ -31,9 +31,11 @@ The Java High Level REST Client supports the following Search APIs:
* <>
* <>
* <>
+* <>
include::search/search.asciidoc[]
include::search/scroll.asciidoc[]
+include::search/multi-search.asciidoc[]
== Miscellaneous APIs