YYDU 2017-07-13
scan
搜索类型和 scroll
API 会一起用来从 elasticsearch 中获得大量文档,不会受到深度分页(deep pagination)的影响。
scroll
滚动搜索 允许我们进行一个初始搜索并保证批量从 Elasticsearch 中拉取结果直到没有更多结果。这看起来有点像传统数据库中的 cursor
。滚动搜索会及时取一个快照。这不会受到后来对索引的改变的影响。通过保持旧数据来实现,所以可以看做是保持了在开始搜索时候的一个“视图”。scan
深度分页的最耗资源的部分就是对结果的整体排序,但是如果我们关闭排序,那么可以消耗极少资源返回所有的文档。对这个情况,我们可以使用 scan
搜索类型。scan
告诉 elasticsearch 不去排序,而是仅仅从每个仍然有结果的分片中返回下一批(batch)。要使用 scan-and-scroll
,我们执行设置 search_type
为 scan
的搜索请求,然后传递一个 scroll
参数告诉 elasticsearch 需要保持 scroll 开放多久:
GET /old_index/_search?search_type=scan&scroll=1m ...(1) { "query": { "match_all": {}}, "size": 1000 }
对该请求的反应不会包含任何的命中 hits,但是会包含一个 _scroll_id
,这是一个 64 位的字符串编码。现在我们将 _scroll_id
传递给 _search/scroll
来检索结果的第一批:
GET /_search/scroll?scroll=1m ...(1) c2Nhbjs1OzExODpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzExOTpRNV9aY1VyUVM 4U0NMd2pjWlJ3YWlBOzExNjpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzExNzpRNV9 aY1VyUVM4U0NMd2pjWlJ3YWlBOzEyMDpRNV9aY1VyUVM4U0NMd2pjWlJ3YWlBOzE 7dG90YWxfaGl0czoxOw== ...(2)
_scroll_id
可以通过 body,URL,或者 query 参数 进行传递注意到,我们这里又指定了 ?scroll=1m
。这个 scroll 终结时间在我们每执行一次 scroll 请求时刷新,所以仅需要给我们足够的时间来处理当前结果的批,而不是整个匹配查询的文档。
这个scroll的响应包含第一批的结果。尽管我们指定了 size
为 1000
,我们获得了更多的文档。在 scan 的时候,size
作用在每个分片上,所以你将会在每批得到最大为 size * number_of_primary_shards
的文档。
注意:scroll 请求同样会返回一个新的
_scroll_id
。每次我们产生下一个 scroll 请求,我们必须传递上一个 scroll 请求的_scroll_id
。
若没有更多的命中,我们就处理完了所有匹配的文档。
注意:有些official Elasticsearch clients 提供 scan-and-scroll 帮助方法来提供易用的封装。
另外一部分,则需要先做聚类、分类处理,将聚合出的分类结果存入ES集群的聚类索引中。数据处理层的聚合结果存入ES中的指定索引,同时将每个聚合主题相关的数据存入每个document下面的某个field下。