Elasticsearch深入:Scroll滚动查询
一、Scroll
search
请求返回一个单一的结果“页”,而 scroll
API 可以被用来检索大量的结果(甚至所有的结果),就像在传统数据库中使用的游标 cursor。
滚动并不是为了实时的用户响应,而是为了处理大量的数据。
例如,为了使用不同的配置来重新索引一个 index 到另一个 index 中去。
为了使用 scroll,初始搜索请求应该在查询中指定 scroll
参数,这可以告诉 Elasticsearch 需要保持搜索的上下文环境多久(参考Keeping the search context alive)。
启用游标查询可以通过在查询的时候设置参数 scroll
的值为我们期望的游标查询的过期时间。 游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不是处理查询结果的所有文档的所需时间。 这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉。 设置这个超时能够让 Elasticsearch 在稍后空闲的时候自动释放这部分资源。
GET /old_index/_search?scroll=1m //保持游标查询窗口一分钟。{
"query": { "match_all": {}},
"sort" : ["_doc"], //关键字 _doc 是最有效的排序顺序。
"size": 1000
}
这个查询的返回结果包括一个字段 _scroll_id
, 它是一个base64编码的长字符串 。 现在我们能传递字段 _scroll_id
到 _search/scroll
查询接口获取下一批结果:
GET /_search/scroll{
"scroll": "1m", //注意再次设置游标查询过期时间为一分钟。
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
}
注意游标查询每次返回一个新字段
_scroll_id
。每次我们做下一次游标查询, 我们必须把前一次查询返回的字段_scroll_id
传递进去。 当没有更多的结果返回的时候,我们就处理完所有匹配的文档了。
这个游标查询返回的下一批结果。 尽管我们指定字段 size
的值为1000,我们有可能取到超过这个值数量的文档。 当查询的时候, 字段 size
作用于单个分片,所以每个批次实际返回的文档数量最大为 size * number_of_primary_shards
。
二、scroll-scan 的高效滚动
使用 from and size
的深度分页,比如说 ?size=10&from=10000
是非常低效的,因为 100,000
排序的结果必须从每个分片上取出并重新排序最后返回 10
条。这个过程需要对每个请求页重复。
scroll API 保持了那些已经返回记录结果,所以能更加高效地返回排序的结果。但是,按照默认设定排序结果仍然需要代价。
一般来说,你仅仅想要找到结果,不关心顺序。你可以通过组合 scroll 和 scan 来关闭任何打分或者排序,以最高效的方式返回结果。你需要做的就是将 search_type=scan 加入到查询的字符串中:
POST /twitter/tweet/_search?scroll=1m&search_type=scan{
"query": {
"match" : {
"title" : "elasticsearch"
}
}
}
设置 search_type 为 scan 可以关闭打分,让滚动更加高效。
扫描式的滚动请求和标准的滚动请求有四处不同:
不算分,关闭排序。结果会按照在索引中出现的顺序返回。
不支持聚合
初始 search 请求的响应不会在 hits 数组中包含任何结果。第一批结果就会按照第一个 scroll 请求返回。
参数 size 控制了每个分片上而非每个请求的结果数目,所以 size 为 10 的情况下,如果命中了 5 个分片,那么每个 scroll 请求最多会返回 50 个结果。
以上是 Elasticsearch深入:Scroll滚动查询 的全部内容, 来源链接: utcz.com/z/512725.html