弹性搜索滚动



我对Elasticsearch的滚动功能有点困惑。在弹性搜索中,每当用户滚动结果集时,是否可以调用搜索API?来自文件

"search_type" => "scan",    // use search_type=scan
"scroll" => "30s",          // how long between scroll requests. should be small!
"size" => 50,               // how many results *per shard* you want back

这是否意味着它将每30秒执行一次搜索,并返回所有结果集,直到没有记录为止?

例如,我的ES总共返回500条记录。我从ES得到的数据是两组记录,每组250条记录。有没有什么方法可以先显示第一组250条记录,当用户滚动时,再显示第二组250条。请建议

您想要的是分页。

您可以通过查询固定大小并设置from参数来实现目标。由于您希望以250个结果的批次设置显示,因此可以设置size = 250,并且对于每个连续的查询,将from的值增加250

GET /_search?size=250                     ---- return first 250 results
GET /_search?size=250&from=250            ---- next 250 results 
GET /_search?size=250&from=500            ---- next 250 results

相反,Scan & scroll允许您通过一次搜索检索大量结果,非常适合将数据重新索引到新索引中等操作。不建议使用它来实时显示搜索结果。

为了简单地解释Scan & scroll,它的本质是扫描扫描请求提供的查询的索引,并返回一个scroll_id。这个scroll_id可以被传递到下一个滚动请求,以返回下一批结果。

考虑以下示例-

# Initialize the scroll
page = es.search(
index = 'yourIndex',
doc_type = 'yourType',
scroll = '2m',
search_type = 'scan',
size = 1000,
body = {
# Your query's body
}
)
sid = page['_scroll_id']
scroll_size = page['hits']['total']

# Start scrolling
while (scroll_size > 0):
print "Scrolling..."
page = es.scroll(scroll_id = sid, scroll = '2m')
# Update the scroll ID
sid = page['_scroll_id']
# Get the number of results that we returned in the last scroll
scroll_size = len(page['hits']['hits'])
print "scroll size: " + str(scroll_size)
# Do something with the obtained page

在上面的例子中,发生了以下事件-

  • 滚动条已初始化。这将返回第一批结果以及scroll_id
  • 对于每个后续滚动请求,发送更新的scroll_id(在上一滚动请求中接收),并返回下一批结果
  • 滚动时间基本上是搜索上下文保持活动的时间。如果下一个滚动请求没有在设定的时间范围内发送,则搜索上下文将丢失,并且不会返回结果。这就是为什么它不应该用于具有大量文档的索引的实时结果显示

您对scroll属性的用途理解错误。这并不意味着弹性搜索将在30秒后获取下一页数据。当您进行第一次滚动请求时,您需要指定何时关闭滚动上下文。scroll参数指示30秒后关闭滚动上下文。

完成第一次滚动请求后,您将返回scroll_id参数作为响应。对于下一页,您需要传递该值以获得滚动响应的下一页。如果您在30秒内没有进行下一次滚动请求,则滚动请求将关闭,您将无法获得该滚动请求的下一页。

您所描述的示例用例实际上是搜索结果分页,它可用于任何搜索查询,并且受10k个结果的限制。当您需要超过10k的限制时,需要scroll请求,使用scroll查询,您甚至可以获取整个文档集合。

这里混淆的原因可能是scroll术语不明确:它意味着查询的类型,也是此类查询的参数的名称(正如其他评论中所提到的,是时候让ES继续等待您获取下一个滚动块了)。

scroll查询量很大,在绝对必要之前应该避免。事实上,在文档中上面写着:

滚动不是用于实时用户请求,而是用于处理大量数据。。。

现在关于您的另一个问题:

在弹性搜索中,每当用户滚动结果集时,是否可以调用搜索API?

是,甚至有几个并行滚动请求有可能:

每个滚动都是独立的,可以像任何滚动请求一样并行处理。

弹性的Scroll API文档也解释了这种行为。

10k的结果大小是默认值,如果需要,可以在运行时覆盖:

PUT { "index" : { "max_result_window" : 500000} }

滚动id的使用寿命在每个滚动请求中定义,参数为"滚动",例如

..
"scroll" : "5m"
..

在最新版本的Elasticsearch中,您将使用search_after。您在那里设置的keep_alive与滚动中的timeout非常相似,只是处理一页所需的时间。

这是因为Elasticsearch将保留您的";搜索上下文";存活了那么长时间,然后将其删除。此外,Elasticsearch不会自动为您获取下一页,您必须使用上一个请求中的ID发送请求。

使用滚动api是明智的,因为在弹性搜索中一次不能获得超过10K的数据。

最新更新