1
0
Эх сурвалжийг харах

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
Nik Everett 7 жил өмнө
parent
commit
8c59e43ac7

+ 91 - 33
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.
- * <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());
+    }
 }

+ 90 - 0
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 <<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.

+ 3 - 1
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

+ 2 - 0
docs/java-rest/high-level/supported-apis.asciidoc

@@ -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