Elasticsearch中扫描和滚动处理深分页问题

来源:互联网 发布:怎么用淘宝注册支付宝 编辑:程序博客网 时间:2024/06/17 05:40

原文地址:http://blog.csdn.net/u014431852/article/details/52830938

1.from-size的限制 
Elasticsearch可以用一种分页的形式来查询数据from-size 
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-from-size.html。

  • from:定义从哪里开始拿数据。
  • size:结果集返回的文档数。

from-size的工作原理是:如size=10&from=90,那么Elasticsearch会从每个Shard里取出100条数据,然后再排序,取出90~100序号的文档。由此观之,from-size的效率必然不会很高,特别是分页越深,需要排序的数据越多,其效率就越低。 
另外,ElasticSearch对于from-size的默认分页深度的10000,如果超过10000就会报错。

当单个结果集超过10000时,可以使用_setting API动态调整索引设置max_result_window的大小,使from + size <= max_result_window 
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/index-modules.html#dynamic-index-settings

更为有效的方法是使用scan and scroll

扫描和滚屏

scan(扫描)搜索类型是和scroll(滚屏)API一起使用来从Elasticsearch里高效地取回巨大数量的结果而不需要付出深分页的代价。

scroll(滚屏)

一个滚屏搜索允许我们做一个初始阶段搜索并且持续批量从Elasticsearch里拉取结果直到没有结果剩下。这有点像传统数据库里的cursors(游标)

滚屏搜索会及时制作快照。这个快照不会包含任何在初始阶段搜索请求后对index做的修改。它通过将旧的数据文件保存在手边,所以可以保护index的样子看起来像搜索开始时的样子。

scan(扫描)

深度分页代价最高的部分是对结果的全局排序,但如果禁用排序,就能以很低的代价获得全部返回结果。为达成这个目的,可以采用scan(扫描)搜索模式。扫描模式让Elasticsearch不排序,只要分片里还有结果可以返回,就返回一批结果。

为了使用scan-and-scroll(扫描和滚屏),需要执行一个搜索请求,将search_type 设置成scan,并且传递一个scroll参数来告诉Elasticsearch滚屏应该持续多长时间。

GET /old_index/_search?search_type=scan&scroll=1m (1){    "query": { "match_all": {}},    "size":  1000}

(1)保持滚屏开启1分钟。

这个请求的应答没有包含任何命中的结果,但是包含了一个Base-64编码的_scroll_id(滚屏id)字符串。现在我们可以将_scroll_id 传递给_search/scroll末端来获取第一批结果:

GET /_search/scroll?scroll=1m      (1)c2Nhbjs1OzExODpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzExOTpRNV9aY1VyUVM4U0 <2>NMd2pjWlJ3YWlBOzExNjpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzExNzpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzEyMDpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzE7dG90YWxfaGl0czoxOw==

(1) 保持滚屏开启另一分钟。

(2) _scroll_id 可以在body或者URL里传递,也可以被当做查询参数传递。

注意,要再次指定?scroll=1m。滚屏的终止时间会在我们每次执行滚屏请求时刷新,所以他只需要给我们足够的时间来处理当前批次的结果而不是所有的匹配查询的document。

这个滚屏请求的应答包含了第一批次的结果。虽然指定了一个1000的size ,但是获得了更多的document。当扫描时,size被应用到每一个分片上,所以我们在每个批次里最多或获得size * number_of_primary_shards(size*主分片数)个document。

注意:

滚屏请求也会返回一个_scroll_id。每次做下一个滚屏请求时,必须传递前一次请求返回的_scroll_id

如果没有更多的命中结果返回,就处理完了所有的命中匹配的document。

+

提示:

一些Elasticsearch官方客户端提供扫描和滚屏的小助手。小助手提供了一个对这个功能的简单封装。

原创粉丝点击