How do I retrieve more than 10000 results/events in Elastic-search
Example query:
GET hostname:port /myIndex/_search {
"size": 10000,
"query": {
"term": { "field": "myField" }
}
}
I have been using the size option knowing that:
index.max_result_window = 100000
But if my query has the size of 650,000 Documents for example or even more, how can I retrieve all of the results in one GET?
I have been reading about the SCROLL, FROM-TO, and the PAGINATION API, but all of them never deliver more than 10K.
This is the example from Elasticsearch Forum, that I have been using:
GET /_search?scroll=1m
Can anybody provide an example where you can retrieve all the documents for a GET search query?
Scroll is the way to go if you want to retrieve a high number of documents, high in the sense that it's way over the 10000 default limit, which can be raised.
The first request needs to specify the query you want to make and the scroll
parameter with duration before the search context times out (1 minute in the example below)
POST /index/type/_search?scroll=1m
{
"size": 1000,
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
In the response to that first call, you get a _scroll_id
that you need to use to make the second call:
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
In each subsequent response, you'll get a new _scroll_id
that you need to use for the next call until you've retrieved the amount of documents you need.
So in pseudo code it looks somewhat like this:
# first request
response = request('POST /index/type/_search?scroll=1m')
docs = [ response.hits ]
scroll_id = response._scroll_id
# subsequent requests
while (true) {
response = request('POST /_search/scroll', scroll_id)
docs.push(response.hits)
scroll_id = response._scroll_id
}
UPDATE:
Please refer to the following answer which is more accurate regarding the best solution for deep pagination: Elastic Search - Scroll behavior
Note that from + size can not be more than the index.max_result_window index setting which defaults to 10,000.
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-from-size.html
So You'll have TWO approches here:
1.add the your query the "track_total_hits": true variable.
GET index/_search
{
"size":1,
"track_total_hits": true
}
2.Use the Scroll API, but then you can't do the from,size in the ordinary way and you'll have to use the Scroll API.
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-scroll.html
for example:
POST /twitter/_search?scroll=1m
{
"size": 100,
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
nodeJS scroll example using elascticsearch:
const elasticsearch = require('elasticsearch');
const elasticSearchClient = new elasticsearch.Client({ host: 'esURL' });
async function getAllData(query) {
const result = await elasticSearchClient.search({
index: '*',
scroll: '10m',
size: 10000,
body: query,
});
const retriever = async ({
data,
total,
scrollId,
}) => {
if (data.length >= total) {
return data;
}
const result = await elasticSearchClient.scroll({
scroll: '10m',
scroll_id: scrollId,
});
data = [...data, ...result.hits.hits];
return retriever({
total,
scrollId: result._scroll_id,
data,
});
};
return retriever({
total: result.hits.total,
scrollId: result._scroll_id,
data: result.hits.hits,
});
}
Another option is the search_after Tag. Joined with a sorting mechanism, you can save your last element in the first return and then ask for results coming after that last element.
GET twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [1463538857, "654323"],
"sort": [
{"date": "asc"},
{"_id": "desc"}
]
}
Worked for me. But until now getting more than 10.000 documents is really not easy.