我在Elasticsearch中有一个小数据库,出于测试目的,我想把所有记录拉回来。我正在尝试使用表单的URL…

http://localhost:9200/foo/_search?pretty=true&q={'matchAll':{''}}

有人能给我你要用来完成这个的URL吗?


当前回答

如果它是一个小数据集(例如1K记录),你可以简单地指定大小:

curl localhost:9200/foo_index/_search?size=1000

不需要match all查询,因为它是隐式的。

如果你有一个中等规模的数据集,比如1M的记录,你可能没有足够的内存来加载它,所以你需要滚动。

滚动就像数据库中的游标。在Elasticsearch中,它会记住你离开的地方,并保持相同的索引视图(即防止搜索器随着刷新而离开,防止段合并)。

api方面,你必须添加一个滚动参数到第一个请求:

curl 'localhost:9200/foo_index/_search?size=100&scroll=1m&pretty'

你会得到第一页和一个滚动ID:

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAADEWbmJlSmxjb2hSU0tMZk12aEx2c0EzUQ==",
  "took" : 0,
...

请记住,您获得的滚动ID和超时都对下一页有效。这里一个常见的错误是指定了一个非常大的超时(scroll的值),这将涵盖处理整个数据集(例如1M条记录)而不是一个页面(例如100条记录)。

要获取下一页,请填写最后一个滚动ID和一个超时,该超时应该持续到获取以下页面:

curl -XPOST -H 'Content-Type: application/json' 'localhost:9200/_search/scroll' -d '{
  "scroll": "1m",
  "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAADAWbmJlSmxjb2hSU0tMZk12aEx2c0EzUQ=="
}'

如果你有很多东西要导出(例如1B文档),你会想要并行化。这可以通过切片滚动来实现。假设您想在10个线程上导出。第一个线程会发出这样的请求:

curl -XPOST -H 'Content-Type: application/json' 'localhost:9200/test/_search?scroll=1m&size=100' -d '{
  "slice": {
    "id": 0, 
    "max": 10 
  }
}'

您将返回第一页和一个滚动ID,与正常的滚动请求完全相同。你会像普通的滚动一样使用它,除了你得到的数据只有十分之一。

其他线程也会做同样的事情,除了id是1,2,3…

其他回答

如果你只是添加一些大的数字作为大小,Elasticsearch会变得非常慢,一种获取所有文档的方法是使用scan和scroll id。

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

在Elasticsearch v7.2中,您可以这样做:

POST /foo/_search?scroll=1m
{
    "size": 100,
    "query": {
        "match_all": {}
    }
}

这样的结果将包含一个_scroll_id,您必须查询它来获得下一个100块。

POST /_search/scroll 
{
    "scroll" : "1m", 
    "scroll_id" : "<YOUR SCROLL ID>" 
}

如果它是一个小数据集(例如1K记录),你可以简单地指定大小:

curl localhost:9200/foo_index/_search?size=1000

不需要match all查询,因为它是隐式的。

如果你有一个中等规模的数据集,比如1M的记录,你可能没有足够的内存来加载它,所以你需要滚动。

滚动就像数据库中的游标。在Elasticsearch中,它会记住你离开的地方,并保持相同的索引视图(即防止搜索器随着刷新而离开,防止段合并)。

api方面,你必须添加一个滚动参数到第一个请求:

curl 'localhost:9200/foo_index/_search?size=100&scroll=1m&pretty'

你会得到第一页和一个滚动ID:

{
  "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAADEWbmJlSmxjb2hSU0tMZk12aEx2c0EzUQ==",
  "took" : 0,
...

请记住,您获得的滚动ID和超时都对下一页有效。这里一个常见的错误是指定了一个非常大的超时(scroll的值),这将涵盖处理整个数据集(例如1M条记录)而不是一个页面(例如100条记录)。

要获取下一页,请填写最后一个滚动ID和一个超时,该超时应该持续到获取以下页面:

curl -XPOST -H 'Content-Type: application/json' 'localhost:9200/_search/scroll' -d '{
  "scroll": "1m",
  "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAADAWbmJlSmxjb2hSU0tMZk12aEx2c0EzUQ=="
}'

如果你有很多东西要导出(例如1B文档),你会想要并行化。这可以通过切片滚动来实现。假设您想在10个线程上导出。第一个线程会发出这样的请求:

curl -XPOST -H 'Content-Type: application/json' 'localhost:9200/test/_search?scroll=1m&size=100' -d '{
  "slice": {
    "id": 0, 
    "max": 10 
  }
}'

您将返回第一页和一个滚动ID,与正常的滚动请求完全相同。你会像普通的滚动一样使用它,除了你得到的数据只有十分之一。

其他线程也会做同样的事情,除了id是1,2,3…

我认为lucene语法是受支持的,所以:

http://localhost: 9200 / foo / _search ?漂亮=真的,q = *: *

size默认为10,因此您可能还需要&size=BIGNUMBER来获取超过10个项目。(其中BIGNUMBER等于一个你认为比你的数据集大的数字)

但是,elasticsearch文档建议对于较大的结果集,使用扫描搜索类型。

EG:

curl -XGET 'localhost:9200/foo/_search?search_type=scan&scroll=10m&size=50' -d '
{
    "query" : {
        "match_all" : {}
    }
}'

然后按照上面建议的文档链接继续请求。

EDIT: scan 2.1.0中已弃用。

与按_doc排序的常规滚动请求相比,Scan并没有提供任何好处。弹性文档链接(由@christophe-roussy提供)

除了@Akira Sendoh,没有人回答如何实际获得所有文档。但是即使是这个解决方案也会使我的ES 6.3服务在没有日志的情况下崩溃。对我来说,使用底层elasticsearch-py库唯一有效的是通过使用scroll() api的扫描助手:

from elasticsearch.helpers import scan

doc_generator = scan(
    es_obj,
    query={"query": {"match_all": {}}},
    index="my-index",
)

# use the generator to iterate, dont try to make a list or you will get out of RAM
for doc in doc_generator:
    # use it somehow

然而,现在更简洁的方法似乎是通过elasticsearch-dsl库,它提供了更抽象、更简洁的调用,例如:http://elasticsearch-dsl.readthedocs.io/en/latest/search_dsl.html#hits

您可以使用size=0,这将返回您所有的文档 例子

curl -XGET 'localhost:9200/index/type/_search' -d '
{
   size:0,
   "query" : {
   "match_all" : {}
    }
}'