From 4f4f9e0af148372fd6d952fa87af6366071210d2 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Fri, 7 Jul 2017 17:48:58 +0200 Subject: [PATCH] [DOCS] revise high level client Search Scroll API docs (#25599) Moved the full example at the end of the page, reduced the number of bullet points for it, and added smaller examples at the beginning of the page. --- .../documentation/SearchDocumentationIT.java | 88 +++++++++---- .../java-rest/high-level/apis/scroll.asciidoc | 120 +++++++++++------- 2 files changed, 138 insertions(+), 70 deletions(-) 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 9f86bb5c12c..0be7124ec9f 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 @@ -36,10 +36,11 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.search.Scroll; import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; @@ -78,31 +79,37 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase { assertFalse(bulkResponse.hasFailures()); } { - // tag::search-scroll-example - final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); // <1> + int size = 1; + // tag::search-scroll-init + SearchRequest searchRequest = new SearchRequest("posts"); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + searchSourceBuilder.query(matchQuery("title", "Elasticsearch")); + searchSourceBuilder.size(size); // <1> + searchRequest.source(searchSourceBuilder); + searchRequest.scroll(TimeValue.timeValueMinutes(1L)); // <2> + SearchResponse searchResponse = client.search(searchRequest); + String scrollId = searchResponse.getScrollId(); // <3> + SearchHits hits = searchResponse.getHits(); // <4> + // end::search-scroll-init + assertEquals(3, hits.getTotalHits()); + assertEquals(1, hits.getHits().length); + assertNotNull(scrollId); - SearchRequest searchRequest = new SearchRequest("posts"); // <2> - searchRequest.source(new SearchSourceBuilder().query(matchQuery("title", "Elasticsearch"))); - searchRequest.scroll(scroll); // <3> + // tag::search-scroll2 + SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); // <1> + scrollRequest.scroll(TimeValue.timeValueSeconds(30)); + SearchResponse searchScrollResponse = client.searchScroll(scrollRequest); + scrollId = searchScrollResponse.getScrollId(); // <2> + hits = searchScrollResponse.getHits(); // <3> + assertEquals(3, hits.getTotalHits()); + assertEquals(1, hits.getHits().length); + assertNotNull(scrollId); + // end::search-scroll2 - SearchResponse searchResponse = client.search(searchRequest); // <4> - String scrollId = searchResponse.getScrollId(); // <5> - - SearchHit[] searchHits = searchResponse.getHits().getHits(); // <6> - while (searchHits != null && searchHits.length > 0) { // <7> - SearchScrollRequest scrollRequest = new SearchScrollRequest() // <8> - .scroll(scroll) // <9> - .scrollId(scrollId); // <10> - - searchResponse = client.searchScroll(scrollRequest); // <11> - scrollId = searchResponse.getScrollId(); // <12> - searchHits = searchResponse.getHits().getHits(); // <13> - } - - ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); // <14> + ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); clearScrollRequest.addScrollId(scrollId); - client.clearScroll(clearScrollRequest); - // end::search-scroll-example + ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest); + assertTrue(clearScrollResponse.isSucceeded()); } { SearchRequest searchRequest = new SearchRequest(); @@ -114,10 +121,10 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase { SearchScrollRequest scrollRequest = new SearchScrollRequest(); scrollRequest.scrollId(scrollId); - // tag::scroll-request-scroll + // tag::scroll-request-arguments scrollRequest.scroll(TimeValue.timeValueSeconds(60L)); // <1> scrollRequest.scroll("60s"); // <2> - // end::scroll-request-scroll + // end::scroll-request-arguments // tag::search-scroll-execute-sync SearchResponse searchResponse = client.searchScroll(scrollRequest); @@ -149,7 +156,7 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase { request.addScrollId(scrollId); // end::clear-scroll-add-scroll-id - List scrollIds = Arrays.asList(scrollId); + List scrollIds = Collections.singletonList(scrollId); // tag::clear-scroll-add-scroll-ids request.setScrollIds(scrollIds); @@ -180,5 +187,34 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase { }); // end::clear-scroll-execute-async } + { + // tag::search-scroll-example + final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); + SearchRequest searchRequest = new SearchRequest("posts"); + searchRequest.scroll(scroll); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + searchSourceBuilder.query(matchQuery("title", "Elasticsearch")); + searchRequest.source(searchSourceBuilder); + + SearchResponse searchResponse = client.search(searchRequest); // <1> + String scrollId = searchResponse.getScrollId(); + SearchHit[] searchHits = searchResponse.getHits().getHits(); + + while (searchHits != null && searchHits.length > 0) { // <2> + SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId); // <3> + scrollRequest.scroll(scroll); + searchResponse = client.searchScroll(scrollRequest); + scrollId = searchResponse.getScrollId(); + searchHits = searchResponse.getHits().getHits(); + // <4> + } + + ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); // <5> + clearScrollRequest.addScrollId(scrollId); + ClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest); + boolean succeeded = clearScrollResponse.isSucceeded(); + // end::search-scroll-example + assertTrue(succeeded); + } } } diff --git a/docs/java-rest/high-level/apis/scroll.asciidoc b/docs/java-rest/high-level/apis/scroll.asciidoc index 65fac026bc0..d96cf569e60 100644 --- a/docs/java-rest/high-level/apis/scroll.asciidoc +++ b/docs/java-rest/high-level/apis/scroll.asciidoc @@ -4,63 +4,73 @@ The Scroll API can be used to retrieve a large number of results from a search request. -In order to use scrolling, several steps need to be executed in a given order: +In order to use scrolling, the following steps need to be executed in the +given order. -* At first, an initial search request with a non-null `scroll` parameter must -be executed. When processing this `SearchRequest`, Elasticsearch detects the -presence of the `scroll` parameter and keeps the search context alive during -the time defined by the parameter. Elasticsearch generates a scroll identifier -associated to this search context and returns it with the first batch of search -results in a `SearchResponse`. -* As a second step, the initial scroll parameter and the new scroll identifier -are set in a `SearchScrollRequest`. This request is executed using the Search -Scroll API and Elasticsearch returns the second batch of results with a new - scroll identifier. This new scroll id can then be used in another `SearchScrollRequest` - to retrieve the next batch of results. This process can be repeated over and - over until no more results are returned. +==== Initialize the search scroll context -* Finally, the last scroll identifier can be deleted using the <> -in order to release the search context. - -[[java-rest-high-search-scroll-example]] -==== Example of Execution - -Here is an example of a scrolled search: +An initial search request with a `scroll` parameter must be executed to +initialize the scroll session through the <>. +When processing this `SearchRequest`, Elasticsearch detects the presence of +the `scroll` parameter and keeps the search context alive for the +corresponding time interval. ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll-example] +include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll-init] -------------------------------------------------- -<1> Define a scroll parameter as a `TimeValue` corresponding to one minute -<2> Create a new `SearchRequest`. See <> -for more information on how to build `SearchRequest`. -<3> Set the `scroll` parameter to the `SearchRequest` -<4> Execute the `SearchRequest` -<5> Retrieve the first scroll id -<6> Retrieve the first batch of search hits -<7> Iterate until there are no more search hits to process -<8> Create a new `SearchScrollRequest` -<9> Set the `scroll` parameter again to tell Elasticsearch to keep the search context -alive for another minute -<10> Set the scroll id -<11> Execute the `SearchScrollRequest` using the Search Scroll API -<12> Retrieve the next scroll id to use in upcoming requests -<13> Retrieve the next batch of search hits -<14> Clear the scroll id using the <>. +<1> Create the `SearchRequest` and its corresponding `SearchSourceBuilder`. +Also optionally set the `size` to control how many results to retrieve at +a time. +<2> Set the scroll interval +<3> Read the returned scroll id, which points to the search context that's +being kept alive and will be needed in the following search scroll call +<4> Retrieve the first batch of search hits + +==== Retrieve all the relevant documents + +As a second step, the received scroll identifier must be set to a +`SearchScrollRequest` along with a new scroll interval and sent through the +`searchScroll` method. Elasticsearch returns another batch of results with +a new scroll identifier. This new scroll identifier can then be used in a +subsequent `SearchScrollRequest` to retrieve the next batch of results, +and so on. This process should be repeated in a loop until no more results are +returned, meaning that the scroll has been exhausted and all the matching +documents have been retrieved. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll2] +-------------------------------------------------- +<1> Create the `SearchScrollRequest` by setting the required scroll id and +the scroll interval +<2> Read the new scroll id, which points to the search context that's +being kept alive and will be needed in the following search scroll call +<3> Retrieve another batch of search hits +<4> + +==== Clear the scroll context + +Finally, the last scroll identifier can be deleted using the <> +in order to release the search context. This happens automatically when the +scroll expires, but it's good practice to do it as soon as the scroll session +is completed. ==== Optional arguments -The following argument can optionally be provided: + +The following arguments can optionally be provided when constructing +the `SearchScrollRequest`: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SearchDocumentationIT.java[scroll-request-scroll] +include-tagged::{doc-tests}/SearchDocumentationIT.java[scroll-request-arguments] -------------------------------------------------- -<1> Scroll value (ie, the time to keep alive the search context) as a `TimeValue` -<2> Scroll value (ie, the time to keep alive the search context) as a `String` +<1> Scroll interval as a `TimeValue` +<2> Scroll interval as a `String` -If no `scroll` value is set for the `SearchScrollRequest`, then the search context -will expire once the initial scroll time expired (ie, the scroll time set in the +If no `scroll` value is set for the `SearchScrollRequest`, the search context will +expire once the initial scroll time expired (ie, the scroll time set in the initial search request). [[java-rest-high-search-scroll-sync]] @@ -82,11 +92,33 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll-execute-asy provided as an argument <2> Called in case of failure. The raised exception is provided as an argument +[[java-rest-high-search-scroll-response]] +==== Response + +The search scroll API returns a `SearchResponse` object, same as the +Search API. + +[[java-rest-high-search-scroll-example]] +==== Full example + +The following is a complete example of a scrolled search. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll-example] +-------------------------------------------------- +<1> Initialize the search context by sending the initial `SearchRequest` +<2> Retrieve all the search hits by calling the Search Scroll api in a loop +until no documents are returned +<3> Create a new `SearchScrollRequest` holding the last returned scroll +identifier and the scroll interval +<4> Process the returned search results +<5> Clear the scroll context once the scroll is completed [[java-rest-high-clear-scroll]] === Clear Scroll API -The search contexts used by the Scroll API are automatically deleted when the scroll +The search contexts used by the Search Scroll API are automatically deleted when the scroll times out. But it is advised to release search contexts as soon as they are not necessary anymore using the Clear Scroll API.