Skip to content

[DOCS] revise high level client Search Scroll API docs #25599

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@
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;
Expand Down Expand Up @@ -78,31 +79,37 @@ public void testScroll() throws IOException {
assertFalse(bulkResponse.hasFailures());
}
{
// tag::search-scroll-example
final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L)); // <1>

SearchRequest searchRequest = new SearchRequest("posts"); // <2>
searchRequest.source(new SearchSourceBuilder().query(matchQuery("title", "Elasticsearch")));
searchRequest.scroll(scroll); // <3>

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>
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);

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

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();
Expand All @@ -114,10 +121,10 @@ public void testScroll() throws IOException {
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);
Expand Down Expand Up @@ -149,7 +156,7 @@ public void onFailure(Exception e) {
request.addScrollId(scrollId);
// end::clear-scroll-add-scroll-id

List<String> scrollIds = Arrays.asList(scrollId);
List<String> scrollIds = Collections.singletonList(scrollId);

// tag::clear-scroll-add-scroll-ids
request.setScrollIds(scrollIds);
Expand Down Expand Up @@ -180,5 +187,34 @@ public void onFailure(Exception e) {
});
// 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);
}
}
}
116 changes: 74 additions & 42 deletions docs/java-rest/high-level/apis/scroll.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<java-rest-high-clear-scroll>>
in order to release the search context.
An initial search request with a `scroll` parameter must be executed to
initialize the scroll session through the <<java-rest-high-search>>.
When processing this `SearchRequest`, Elasticsearch detects the presence of
the `scroll` parameter and keeps the search context alive for the
corresponding time interval.

[[java-rest-high-search-scroll-example]]
==== Example of Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll-init]
--------------------------------------------------
<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

Here is an example of a scrolled search:
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-scroll-example]
include-tagged::{doc-tests}/SearchDocumentationIT.java[search-scroll2]
--------------------------------------------------
<1> Define a scroll parameter as a `TimeValue` corresponding to one minute
<2> Create a new `SearchRequest`. See <<java-rest-high-search>>
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 <<java-rest-high-clear-scroll>>.
<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 <<java-rest-high-clear-scroll>>
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have an example call?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. I didn't add that because it felt like repeating the clear scroll docs, so I thought the link is enough, and the clear scroll code is already in the full example at the end. Do you think that's ok?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me, though I wonder why we have clear scroll docs outside of the scroll docs. I think they'd make more sense right here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just because every API is rendered in its own page.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with it as is.


==== 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]]
Expand All @@ -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.

Expand Down