前言
1、scroll原理
scroll API可用于从单个搜索请求中检索大量结果(甚至所有结果),其方式与在传统数据库上使用光标的方式大致相同。
第一次查询时,会生产当时查询的快照,后续的查询只要携带上次返回的scroll_id即可 。
2、特点
可以深查询(甚至全部数据),性能、效率优于from+size方式。
快照查询,在scroll查询期间 ,外部对索引内的数据进行增删改查等操作不会影响到这个快照的结果。
使用
1、kibana中测试示例
第一次查询 ,并设置上下文scroll_id存活时间为1分钟。
POST book/_search?scroll=1m
{
"size": 10,
"query": {
"match" : {
"name": "明朝的那些事"
}
}
}
响应:
{
"_scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAD1K-0WdzM3OF9WRVFUcXk3bFNDcjZKZ1pZdw==",
"took":22,
"timed_out":false,
"_shards":{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":1302017,
"max_score":2.5815613,
"hits":Array[10]
}
}
后续查询,使用前一个scroll_id即可:
POST _search/scroll
{
"scroll":"1m",
"scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAD1K-0WdzM3OF9WRVFUcXk3bFNDcjZKZ1pZdw=="
}
2、Java代码示例
首次调用:
// 构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
...
searchSourceBuilder.from(100).size(10);
// 构建请求
SearchRequest searchRequest = new SearchRequest("book");
searchRequest.types("title");
// ===》 关键是多加了这句话
searchRequest.scroll(new Scroll(TimeValue.timeValueMinutes(1)));
searchRequest.source(searchSourceBuilder);
return client.search(searchRequest, RequestOptions.DEFAULT);
后续调用:
// 传入上次返回的scroll_id
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
scrollRequest.scroll(TimeValue.timeValueMinutes(1));
SearchResponse response = client.getRestClient().scroll(scrollRequest, RequestOptions.DEFAULT);
return response;