Elasticsearch查询返回所有记录


490

我在Elasticsearch中有一个小型数据库,出于测试目的,我想拉回所有记录。我正在尝试使用以下形式的网址...

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

有人可以给我您用来完成此操作的URL吗?


1
...其中“ foo”是要显示其所有记录的索引的名称。
jonatan

Answers:


744

我认为支持lucene语法是这样的:

http://localhost:9200/foo/_search?pretty=true&q=*:*

大小默认为10,因此您可能还需要&size=BIGNUMBER获取10个以上的商品。(其中BIGNUMBER等于您认为大于数据集的数字)

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

例如:

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

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

编辑:scan2.1.0中已弃用。

scanscroll按排序的常规请求相比没有任何好处_doc链接到弹性文档(由@ christophe-roussy发现)


6
谢谢。这是我想出的最后一个命令,它返回了我现在需要的... localhost:9200 / foo / _search?size = 50&pretty = true&q = *:*
John Livermore

2
添加到@史蒂夫的答案,你可以找到的参数列表,elasticsearch理解在这个环节elasticsearch.org/guide/reference/api/search/uri-request
Karthick

1
感谢@Steve的回答。我认为这对于一个新问题来说意义不大。它在任何地方都没有明确说明,因此我想在这里要求进行验证。
Churro 2013年

8
您应该真正使用scan + scroll-requests。如果确实使用size = BIGNUMBER,请注意,Lucene会为该数字的分数分配内存,因此请不要使其过大。:)
Alex Brasetvik


137
http://127.0.0.1:9200/foo/_search/?size=1000&pretty=1
                                   ^

注意大小参数,它将显示的命中次数从默认(10)增加到每个分片1000。

http://www.elasticsearch.org/guide/zh-CN/elasticsearch/reference/current/search-request-from-size.html


10
但是要记住一件事(来自Elasticsearch文档):请注意,from + size不能大于index.max_result_window索引设置,该设置默认为10,000。
user3078523 '18

2
这将返回1000,不是全部,user3078523是正确的,此方法的限制为max_result_window
stelios

1
它有一个最大值,而且(如果您有成千上万的记录要获取)要达到该最大值是一个相当繁琐的方法。相反,您应该使用“滚动”查询。
哈里·伍德

37

elasticsearch(ES)支持GET或POST请求,以从ES群集索引中获取数据。

当我们执行GET时:

http://localhost:9200/[your index name]/_search?size=[no of records you want]&q=*:*

当我们执行POST时:

http://localhost:9200/[your_index_name]/_search
{
  "size": [your value] //default 10
  "from": [your start index] //default 0
  "query":
   {
    "match_all": {}
   }
}   

我建议将UI插件与elasticsearch一起使用http://mobz.github.io/elasticsearch-head/ 这将帮助您更好地了解创建的索引并测试索引。


3
正如另一个用户提到的: from+ size不能超过index.max_result_window默认设置为10,000 的索引设置
stelios

这种方法有一个最大值,而且(如果您有成千上万的记录要获取)它是一个相当繁琐的方法,要达到该最大值。相反,您应该使用“滚动”查询
哈里·伍德

奇怪的是,官方文档显示curl -XGET ... -d '{...}'这是一种un混合要求的官方样式。感谢您显示正确的GET和POST格式。
杰西·奇斯霍尔姆

28

注意:答案与旧版本的Elasticsearch有关0.90。从那时起发布的版本具有更新的语法。请参考其他答案,这些答案可能会为您寻找的最新答案提供更准确的答案。

以下查询将返回您要返回的NO_OF_RESULTS。

curl -XGET 'localhost:9200/foo/_search?size=NO_OF_RESULTS' -d '
{
"query" : {
    "match_all" : {}
  }
}'

现在,这里的问题是您希望返回所有记录。因此,自然地,在编写查询之前,您不会知道NO_OF_RESULTS的值。

我们如何知道您的文档中存在多少记录?只需在下面键入查询

curl -XGET 'localhost:9200/foo/_search' -d '

这将为您提供类似于以下结果的结果

 {
hits" : {
  "total" :       2357,
  "hits" : [
    {
      ..................

结果总数告诉您文档中有多少记录可用。因此,这是了解NO_OF RESULTS值的好方法

curl -XGET 'localhost:9200/_search' -d ' 

搜索所有索引中的所有类型

curl -XGET 'localhost:9200/foo/_search' -d '

搜索foo索引中的所有类型

curl -XGET 'localhost:9200/foo1,foo2/_search' -d '

搜索foo1和foo2索引中的所有类型

curl -XGET 'localhost:9200/f*/_search

搜索任何以f开头的索引中的所有类型

curl -XGET 'localhost:9200/_all/type1,type2/_search' -d '

所有索引中的搜索类型用户和推文


9
默认情况下,除非基本查询中包含大小参数,否则ES将返回10个结果。
lfender6445 2014年

先前的回应是三岁。将其更新为当前版本。
vjpandian

19

这是我使用python客户端发现的最佳解决方案

  # 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

https://gist.github.com/drorata/146ce50807d16fd4a6aa

使用Java客户端

import static org.elasticsearch.index.query.QueryBuilders.*;

QueryBuilder qb = termQuery("multi", "test");

SearchResponse scrollResp = client.prepareSearch(test)
        .addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
        .setScroll(new TimeValue(60000))
        .setQuery(qb)
        .setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll
//Scroll until no hits are returned
do {
    for (SearchHit hit : scrollResp.getHits().getHits()) {
        //Handle the hit...
    }

    scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
} while(scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.

https://www.elastic.co/guide/zh-CN/elasticsearch/client/java-api/current/java-search-scrolling.html


谢谢马克,那正是我想要的!就我而言(ELK 6.2.1,python 3),自从ELK 6.0以来,search_type参数无效,不再需要document_type
Christoph Schranz

完美的解决方案!谢谢。我正在使用elasticsearch_dsl==5.4.0,它没有工作search_type = 'scan',
Usman Maqbool,

ES 6.3。此示例使我的Elasticsearch服务崩溃,尝试size=10000在5至7次迭代之间的某个时间滚动110k文档。有status=127main ERROR Null object returned for RollingFile in Appendersmain ERROR Unable to locate appender "rolling" for logger config "root"无登录/var/log/elasticsearch/elasticsearch.log
斯泰利奥斯

作为记录,python客户端实现了一个scan辅助功能,该功能可以在幕后进行滚动(自Leat版本5.xx起)
MCMZL,

search_type = 'scan'不推荐使用。没有这些功能,类似的代码也可以使用,尽管有些有趣的差异已经很好地掩藏在旧文档中。elastic.co/guide/en/elasticsearch/reference/1.4/… 特别是,当迁移为不使用search_type = scan时,该第一个“搜索”查询将随第一批结果一起处理。
哈里·伍德

12

如果您仅添加一些大数字作为大小,Elasticsearch的速度将大大降低,一种用于获取所有文档的方法是使用扫描和滚动ID。

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

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

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

由此产生的结果将包含一个_scroll_id,您必须查询该_scroll_id才能获取下一个100块。

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

1
该答案需要更多更新。search_type=scan现在已弃用。因此,您应该删除它,但是随后的行为有所改变。第一批数据从初始搜索调用返回。您提供的链接确实显示了正确的方法。
哈里·伍德

1
我的评论确实是要注意的是,您不能随便添加任何数字作为大小,因为它会慢很多。因此,我删除了代码示例,人们可以按照链接获取正确的代码。
WoodyDRN

1
@WoodyDRN最好在您的答案中包含代码(即使它变旧了),以便在链接消失时仍然可用。
三叉戟

11

使用server:9200/_stats也得到统计您所有的别名..喜欢的大小和每别名元素的数量,这是非常有用的,并提供有用的信息


2
但是,据我所记得,ES仅允许每个请求获取16000数据。因此,如果数据高于16000,则此解决方案还不够。
Aminah Nuraini '16

10

如果您想提取成千上万条记录,那么...有些人给出了使用'scroll'的正确答案(注意:有些人还建议使用“ search_type = scan”。已弃用,在v5.0中已删除。您不需要它)

从“搜索”查询开始,但指定“滚动”参数(此处我使用1分钟超时):

curl -XGET 'http://ip1:9200/myindex/_search?scroll=1m' -d '
{
    "query": {
            "match_all" : {}
    }
}
'

这包括您的第一个“批次”匹配。但是我们在这里还没有完成。上面的curl命令的输出将是这样的:

{ “_scroll_id”: “c2Nhbjs1OzUyNjE6NU4tU3BrWi1UWkNIWVNBZW43bXV3Zzs1Mzc3OkhUQ0g3VGllU2FhemJVNlM5d2t0alE7NTI2Mjo1Ti1TcGtaLVRaQ0hZU0FlbjdtdXdnOzUzNzg6SFRDSDdUaWVTYWF6YlU2Uzl3a3RqUTs1MjYzOjVOLVNwa1otVFpDSFlTQWVuN211d2c7MTt0b3RhbF9oaXRzOjIyNjAxMzU3Ow ==”, “花”:109, “TIMED_OUT”:假, “_碎片”:{ “总”:5, “成功”:5, “失败”:0}, “点击” :{“ total”:22601357,“ max_score”:0.0,“ hits”:[]}}

拥有_scroll_id十分重要,因为下一步您应该运行以下命令:

    curl -XGET  'localhost:9200/_search/scroll'  -d'
    {
        "scroll" : "1m", 
        "scroll_id" : "c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1" 
    }
    '

但是,传递scroll_id并非旨在手动完成的事情。最好的选择是编写代码来做到这一点。例如在Java中:

    private TransportClient client = null;
    private Settings settings = ImmutableSettings.settingsBuilder()
                  .put(CLUSTER_NAME,"cluster-test").build();
    private SearchResponse scrollResp  = null;

    this.client = new TransportClient(settings);
    this.client.addTransportAddress(new InetSocketTransportAddress("ip", port));

    QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
    scrollResp = client.prepareSearch(index).setSearchType(SearchType.SCAN)
                 .setScroll(new TimeValue(60000))                            
                 .setQuery(queryBuilder)
                 .setSize(100).execute().actionGet();

    scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
                .setScroll(new TimeValue(timeVal))
                .execute()
                .actionGet();

现在,在最后一条命令上的LOOP使用SearchResponse提取数据。


6

简单!您可以使用sizefrom参数!

http://localhost:9200/[your index name]/_search?size=1000&from=0

然后您from逐渐改变直到获得所有数据。


4
如果数据包含许多文档,则永远不要使用此方法。每次您转到“下一页”,Elastic的速度将越来越慢!改用SearchAfter
Joshlo '17

3
另外,如果总体数据大小超过10000,则此解决方案将不起作用。选项size = 1000&from = 10001将失败。
iclman

2
确实失败了。参数from+ size不能超过index.max_result_window索引设置,该设置默认为10,000
stelios

1
如果数据包含成千上万的文档,则正确的答案是使用“滚动”查询。
哈里·伍德

使用fromsize方法,您将遇到“深度分页”问题。使用滚动API可以转储所有文档。
Daniel Schneiter

5

调整大小的最佳方法是在URL前面使用size = number

Curl -XGET "http://localhost:9200/logstash-*/_search?size=50&pretty"

注意:可以在此大小中定义的最大值是10000。对于任何大于一万的值,它都希望您使用滚动功能,这将最大程度地降低对性能的影响。


从哪个版本开始出现最大尺寸?
WoodyDRN

这可能是某种程度上的“最佳”方法,但确实有点点头。如果您有成千上万的记录,那么最好的方法是“滚动”查询。
哈里·伍德

使用from和size方法,您将遇到“深度分页”问题。使用滚动API可以转储所有文档。
Daniel Schneiter

5

您可以使用_countAPI来获取size参数的值:

http://localhost:9200/foo/_count?q=<your query>

返回{count:X, ...}。提取值“ X”,然后执行实际查询:

http://localhost:9200/foo/_search?q=<your query>&size=X

1
像这样将大小设置为X,可能会出现令人惊讶的并发故障:考虑如果在进行计数和设置下一个查询的大小之间添加了一条记录,会发生什么情况……而且如果您有成千上万的记录需要获取, ,那是错误的方法。相反,您应该使用“滚动”查询。
哈里·伍德


4

尺寸参数将显示的匹配次数从默认值(10)增加到500。

http:// localhost:9200 / [indexName] / _search?pretty = true&size = 500&q = *:*

更改逐步以获取所有数据。

http:// localhost:9200 / [indexName] / _search?size = 500&from = 0

3

对于Elasticsearch 6.x

请求: GET /foo/_search?pretty=true

响应:在Hits-> total中,给出文档的数量

    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": 1001,
        "max_score": 1,
        "hits": [
          {

3

如果它是一个小的数据集(例如1K记录),则只需指定size

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

比赛的所有查询是不需要的,因为它是隐含的。

如果您有中等大小的数据集(例如1M条记录),则可能没有足够的内存来加载它,因此需要滚动

滚动就像数据库中的光标。在Elasticsearch中,它会记住您离开的地方并保持相同的索引视图(即,防止搜索者进行刷新,防止分段合并))。

在API方面,您必须向第一个请求添加一个scroll参数:

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,就像正常的滚动请求一样。除了获得1/10的数据外,您将完全像常规滚动一样使用它。

其他线程将执行相同的操作,除了id将是1、2、3 ...



2

默认情况下,Elasticsearch返回10条记录,因此应显式提供大小。

根据要求添加大小以获取所需的记录数。

http:// {host}:9200 / {index_name} / _search?pretty = true&size =(记录数)

注意:最大页面大小不能超过index.max_result_window索引设置,该设置默认为10,000。


2

从Kibana DevTools获得:

GET my_index_name/_search
{
  "query": {
    "match_all": {}
  }
}


1

通过提供大小,elasticSearch将返回的最大结果为10000

curl -XGET 'localhost:9200/index/type/_search?scroll=1m' -d '
{
   "size":10000,
   "query" : {
   "match_all" : {}
    }
}'

之后,您必须使用Scroll API来获取结果并获取_scroll_id值,并将此值放入scroll_id

curl -XGET  'localhost:9200/_search/scroll'  -d'
{
   "scroll" : "1m", 
   "scroll_id" : "" 
}'

滚动API应该从第一个请求开始就使用。
Daniel Schneiter

1

官方文档提供了此问题的答案!你可以在这里找到它。

{
  "query": { "match_all": {} },
  "size": 1
}

您只需将大小(1)替换为要查看的结果数!


问题的作者要求的是“所有”结果,而不是预定数量的结果。虽然发布指向文档的链接很有帮助,但是文档没有描述如何实现此目的,您的答案也没有。
Maarten00 '19

使用from和size方法,您将遇到“深度分页”问题。使用滚动API可以转储所有文档。
Daniel Schneiter

0

要返回所有索引中的所有记录,您可以执行以下操作:

curl -XGET http://35.195.120.21:9200/_all/_search?size=50&pretty

输出:

  "took" : 866,
  "timed_out" : false,
  "_shards" : {
    "total" : 25,
    "successful" : 25,
    "failed" : 0
  },
  "hits" : {
    "total" : 512034694,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "grafana-dash",
      "_type" : "dashboard",
      "_id" : "test",
      "_score" : 1.0,
       ...

0
curl -XGET '{{IP/localhost}}:9200/{{Index name}}/{{type}}/_search?scroll=10m&pretty' -d '{
"query": {
"filtered": {
"query": {
"match_all": {}
}}'

尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
Stamos

0

除了@Akira Sendoh,没有人回答了如何实际获取所有文档。但是,即使该解决方案也使没有日志的ES 6.3服务崩溃。使用低级elasticsearch-py库对我来说唯一有效的方法是使用api的扫描助手scroll()

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


0

如果仍然有人需要像我一样从某些情况下从Elasticsearch检索所有数据,这就是我所做的。而且,所有数据意味着所有索引和所有文档类型。我正在使用Elasticsearch 6.3

curl -X GET "localhost:9200/_search?pretty=true" -H 'Content-Type: application/json' -d'
{
    "query": {
        "match_all": {}
    }
}
'

Elasticsearch参考


0

这是完成您想要的查询(我建议使用Kibana,因为它有助于更​​好地理解查询)

GET my_index_name/my_type_name/_search
{
   "query":{
      "match_all":{}
   },
   size : 20,
   from : 3
}

要获取所有记录,您必须使用“ match_all”查询。

size是您要获取的记录数(限制种类)。默认情况下,ES仅返回10条记录

from就像跳过,跳过前3条记录。

如果要获取所有记录,只需在从Kibana命中此查询并将其与“ size”一起使用时,使用结果中“ total”字段中的值即可。


此查询的限制是size + from必须小于或等于“ index.max_result_window”。对于大量文档(默认情况下为10000+),此查询不适用。
KarelHusa

0

使用Elasticsearch 7.5.1

http://${HOST}:9200/${INDEX}/_search?pretty=true&q=*:*&scroll=10m&size=5000

如果您还可以使用&size = $ {number}指定数组的大小

万一你不知道你索引

http://${HOST}:9200/_cat/indices?v

0

使用kibana控制台和my_index作为索引来搜索以下内容。要求索引仅返回索引的4个字段,您还可以添加大小以指示索引希望返回多少文档。从ES 7.6开始,您应该使用_source而不是filter,它会更快地响应。

GET /address/_search
 {
   "_source": ["streetaddress","city","state","postcode"],
   "size": 100,
   "query":{
   "match_all":{ }
    }   
 }

-5

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

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

1
这将返回累积的信息,但不会返回匹配本身
user732456'3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.