繁体   English   中英

弹性搜索滚动

[英]Elasticsearch Scroll

我对 Elasticsearch 的滚动功能有点困惑。 在 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属性的目的。 这并不意味着elasticsearch将在30秒后获取下一页数据。 在执行第一个滚动请求时,您需要指定何时关闭滚动上下文。 scroll参数指示30秒后关闭滚动上下文。

在执行第一个滚动请求后,您将获得响应的scroll_id参数。 对于下一页,您需要传递该值以获得滚动响应的下一页。 如果您将在30秒内不执行下一个滚动请求,则该滚动请求将被关闭,您将无法获取该滚动请求的下一页。

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

造成混淆的原因可能是scroll术语含糊不清:它表示查询的类型,并且也是此类查询的参数名称(如其他注释中所述 ,这是ES会继续等待您的时间)获取下一个滚动块)。

scroll查询很繁琐,应避免使用,直到绝对必要为止。 实际上,在文档中它说:

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

现在关于另一个问题:

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

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

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

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

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

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

在每个滚动请求中使用参数“ scroll”定义滚动ID的生存时间,例如

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

使用 scroll api 是明智的,因为在 elasticsearch 中一次不能获得超过 10K 的数据。

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

那是因为 Elasticsearch 会在这段时间内让您的“搜索上下文”保持活动状态,然后将其删除。 此外,Elasticsearch 不会自动为您获取下一页,您必须通过发送带有上次请求中的 ID 的请求来实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM