ELK:如何在Elastic-search中检索超过10000个结果/事件

Fra*_*nco 24 pagination scroll get resultset elasticsearch

问题: 在GET /搜索查询中通过搜索检索弹性搜索超过10,000个结果.

GET hostname:port /myIndex/_search { 
    "size": 10000,
    "query": {
        "term": { "field": "myField" }
    }
}
Run Code Online (Sandbox Code Playgroud)

我一直在使用size选项知道:

index.max_result_window = 100000

但是,如果我的查询大小为650,000个文档,或者甚至更多,我如何在一个GET中检索所有结果?

我一直在阅读有关SCROLL,FROM-TO和PAGINATION API的信息,但它们都不会超过10K.

这是Elasticsearch论坛的例子,我一直在使用:

GET /_search?scroll=1m
Run Code Online (Sandbox Code Playgroud)

任何人都可以提供一个示例,您可以在其中检索GET搜索查​​询的所有文档吗?

非常感谢你.

Val*_*Val 26

如果你想要检索大量的文档,那么滚动就是你要去的方法,因为它超过10000默认限制,可以提高.

第一个请求需要在搜索上下文超时之前指定要进行的查询和scroll持续时间的参数(在下面的示例中为1分钟)

POST /index/type/_search?scroll=1m
{
    "size": 1000,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在第一次通话的响应中,_scroll_id您需要使用它来进行第二次通话:

POST /_search/scroll 
{
    "scroll" : "1m", 
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
}
Run Code Online (Sandbox Code Playgroud)

在每个后续响应中,您将获得一个新的_scroll_id,您需要在下次调用时使用它,直到您检索到所需的文档数量.

所以在伪代码中看起来有点像这样:

# first request
response = request('POST /index/type/_search?scroll=1m')
docs = [ response.hits ]
scroll_id = response._scroll_id

# subsequent requests
while (true) {
   response = request('POST /_search/scroll', scroll_id)
   docs.push(response.hits)
   scroll_id = response._scroll_id
}
Run Code Online (Sandbox Code Playgroud)

  • 你绝对可以[增加`index.max_result_window`值](https://www.elastic.co/guide/en/elasticsearch/reference/5.1/index-modules.html#dynamic-index-settings)但你会如果您想一次性获得 650000 个文档,则冒着关闭集群的风险。 (2认同)

Era*_*led 22

请注意 from + size 不能超过 index.max_result_window 索引设置,默认为 10,000。

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-from-size.html

所以你会在这里有两个方法:

1.添加您的查询“ track_total_hits ”:true变量。

GET index/_search
{
    "size":1,
    "track_total_hits": true
}
Run Code Online (Sandbox Code Playgroud)

2.使用Scroll API,但是你不能用普通的方式做from,size,你必须使用Scroll API。

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-scroll.html

例如:

 POST /twitter/_search?scroll=1m
{
"size": 100,
"query": {
    "match" : {
        "title" : "elasticsearch"
    }
}
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可以解决 OP 的问题,但最好包含有关代码如何解决 OP 问题的解释。通过这种方式,未来的访问者可以从您的帖子中学习,并将其应用到自己的代码中。SO 不是编码服务,而是知识资源。此外,高质量、完整的答案更有可能获得赞成。这些功能以及所有帖子都是独立的要求是 SO 作为平台的一些优势,这使其与论坛区分开来。您可以编辑以添加附加信息和/或用源文档补充您的解释。 (2认同)

zoo*_*lin 15

使用elasticsearch 的nodeJS 滚动示例:

const elasticsearch = require('elasticsearch');
const elasticSearchClient = new elasticsearch.Client({ host: 'esURL' });

async function getAllData(query) {
  const result = await elasticSearchClient.search({
    index: '*',
    scroll: '10m',
    size: 10000,
    body: query,
  });

  const retriever = async ({
    data,
    total,
    scrollId,
  }) => {
    if (data.length >= total) {
      return data;
    }

    const result = await elasticSearchClient.scroll({
      scroll: '10m',
      scroll_id: scrollId,
    });

    data = [...data, ...result.hits.hits];

    return retriever({
      total,
      scrollId: result._scroll_id,
      data,
    });
  };

  return retriever({
    total: result.hits.total,
    scrollId: result._scroll_id,
    data: result.hits.hits,
  });
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*Dan 7

另一个选项是search_after标签。与排序机制相结合,您可以将最后一个元素保存在第一个返回中,然后询问最后一个元素之后的结果。

GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [1463538857, "654323"],
    "sort": [
        {"date": "asc"},
        {"_id": "desc"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

为我工作。但到目前为止,获取一万多份文件确实不容易。

  • 这是唯一可以让您不受限制地滚动的正确答案。您可以增加滚动窗口,但除了 ES 建议不要这样做(并且滚动会产生成本)之外,它始终受到滚动窗口大小的限制。search_after 没有这个限制,尽管它的一个缺点是您没有位置数据(因此您无法“计算”您所在的页面) (3认同)
  • 1463538857 和“654323”是什么 (2认同)