ES如何查询索引的全量数据

这篇具有很好参考价值的文章主要介绍了ES如何查询索引的全量数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述
查询全表数据也是日常工作中常见的一种查询场景。
在ES如果我们使用match_all查询索引的全量数据时,默认只会返回10条数据。
那么在ES如何查询索引的全量数据呢?

小实验
1、索引和数据准备
PUT book
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text", "analyzer": "ik_smart"
      },
      "price": {
        "type": "double"
      }
    }
  }
}

PUT /book/_bulk
{ "create": { } }
{"name": "java编程思想","price": 100}
{ "create": { } }
{"name": "ES实战","price": 120}
{ "create": { } }
{"name": "ES从入门到精通","price": 60}
{ "create": { } }
{"name": "微服务架构 设计模式","price": 160}
{ "create": { } }
{"name": "架构真经","price": 90}
{ "create": { } }
{"name": "spring boot实战","price": 50}
{ "create": { } }
{"name": "高性能mysql","price": 80}
{ "create": { } }
{"name": "java进阶1","price": 10}
{ "create": { } }
{"name": "java进阶2","price": 20}
{ "create": { } }
{"name": "java进阶3","price": 30}
{ "create": { } }
{"name": "java进阶4","price": 40}
{ "create": { } }
{"name": "java进阶5","price": 50}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2、match_all全匹配查询
GET book/_search
1
等同于

GET book/_search
{
  "query": {
    "match_all": {}
  }
}
1
2
3
4
5
6
发现只返回了10条记录。
这样因为_search查询默认采用的是分页查询,每页记录数size的默认值为10.

3、添加size参数
GET book/_search
{
  "query": {
    "match_all": {}
  },
  "size": 100
}
1
2
3
4
5
6
7
将size值设置为100,而我们只添加了13条记录,所以成功返回索引的全量记录。

4、size大于10000
GET book/_search
{
  "query": {
    "match_all": {}
  },
  "size": 20000
}
1
2
3
4
5
6
7
返回结果:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "Result window is too large, from + size must be less than or equal to: [10000] but was [20000]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."
      }
    ],
1
2
3
4
5
6
7
8
异常说明:
1、查询结果的窗口太大,from + size的结果必须小于或等于10000,而当前查询结果的窗口为20000。
2、可以采用scroll api更高效的请求大量数据集。
3、查询结果的窗口的限制可以通过参数index.max_result_window进行设置。

index.max_result_window
The maximum value of from + size for searches to this index. Defaults to 10000. Search requests take heap memory and time proportional to from + size and this limits that memory. See Scroll or Search After for a more efficient alternative to raising this.
说明:
参数index.max_result_window主要用来限制单次查询满足查询条件的结果窗口的大小,窗口大小由from + size共同决定。不能简单理解成查询返回给调用方的数据量。
这样做主要是为了限制内存的消耗。
请求大数据集推荐采用Scroll or Search After 。
比如:from为1000000,size为10,逻辑意义是从满足条件的数据中取1000000到(1000000 + 10)的记录。这时ES一定要先将(1000000 + 10)的记录(即result_window)加载到内存中,再进行分页取值的操作。
尽管最后我们只取了10条数据返回给客户端,但ES进程执行查询操作的过程中确需要将(1000000 + 10)的记录都加载到内存中,可想而知对内存的消耗有多大。
这也是ES中不推荐采用(from + size)方式进行深度分页的原因。

同理,from为0,size为1000000时,ES进程执行查询操作的过程中确需要将1000000 条记录都加载到内存中再返回给调用方,也会对ES内存造成很大压力。

1.参数设置
PUT book/_settings

  "index.max_result_window" :"5"
}
1
2
3
4
注意:
1、此方法是设置单索引,如果需要更改索引需要将book换成_all
2、即使换成_all,对于新增的索引,还是默认的10000

2.查看参数
查看所有索引中的index.max_result_window值:

GET _all/_settings/index.max_result_window
1
查看book索引的_settings配置:

GET book/_settings
1
查看_settings配置中的参数index.max_result_window的值:

GET book/_settings/index.max_result_window
1
Scroll api实践
改动index.max_result_window参数值的大小,只能解决一时的问题,当索引的数据量持续增长时,在查询全量数据时还是会出现问题。而且会增加ES服务器内存大结果集消耗完的风险。
最佳实践还是根据异常提示中的采用scroll api更高效的请求大量数据集。

1.DSL命令查询
1、查询命令中新增scroll=1m,说明采用游标查询,保持游标查询窗口一分钟。
2、这里由于测试数据量不够,所以size值设置为2。实际使用中为了减少游标查询的次数,可以将值适当增大,比如设置为1000。

GET /book/_search?scroll=1m 
{
    "query": { "match_all": {}},
    "size":  2
}
1
2
3
4
5
查询结果:
除了返回前2条记录,还返回了一个游标ID值_scroll_id。

{
  "_scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFm1ab2pDVEpiVGh5ZWthYnRQanB5YlEAAAAAABRP-xZHYWJiZzJGNFJYQ1RPS0dZb1VwejRR",
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  ……
}
1
2
3
4
5
6
7
8
9
10
11
12
采用游标id查询:

GET /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFm1ab2pDVEpiVGh5ZWthYnRQanB5YlEAAAAAABRP5BZHYWJiZzJGNFJYQ1RPS0dZb1VwejRR"
}
1
2
3
4
5
说明:
多次根据scroll_id游标查询,直到没有数据返回则结果查询。。
采用游标查询索引全量数据,更安全高效,限制了单次对内存的消耗。

2.java高级API实现
/**
 * 通过游标查询所有数据
 * @return
 */
public  <T> List<T> searchAllData(SearchRequest searchRequest, Class<T> clazz)  {
    List<T> tList = new ArrayList<>();
    final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
    searchRequest.scroll(scroll);
    try{
        SearchResponse searchResponse = highLevelClient.search(searchRequest);
        String scrollId = searchResponse.getScrollId();
        log.info("ES查询DSL语句:\nGET  {}\n{}", String.format("/%s/_search", searchRequest.indices()[0]), searchRequest.source());
        //打印命中数量
        log.info("命中总数量:{}", searchResponse.getHits().getTotalHits());
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        while (searchHits != null && searchHits.length > 0) {
            SearchHits hits = searchResponse.getHits();
            List<T> resultList = Arrays.stream(hits.getHits()).map(e -> {
                String jsonStr = e.getSourceAsString();
                return JSON.parseObject(jsonStr, clazz);
            }).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(resultList)){
                tList.addAll(resultList);
            }
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(scroll);
            searchResponse = highLevelClient.searchScroll(scrollRequest);
            searchHits = searchResponse.getHits().getHits();
        }

        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
        clearScrollRequest.addScrollId(scrollId);
        ClearScrollResponse clearScrollResponse = highLevelClient.clearScroll(clearScrollRequest);
        boolean succeeded = clearScrollResponse.isSucceeded();
    }catch (Exception e){
        log.error("执行EsService的searchAllData方法出现异常", e);
    }
    return  tList;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
注意:
1、尽管通过采用Scroll API提高的查询全量数据的性能,减少了ES服务器的内存消耗。但是当返回结果集过大的时候,也会出现将调用方应用的内存撑爆的风险。
2、推荐的做法是:在调用searchAllData方法查询索引全量数据时,在方法内部添加返回记录条数的限制。避免出现返回几百万、甚至上千万的结果集,导致调用方程序由于内存吃完而宕机。

总结
1、本文主要介绍了如何通过Scroll API查询索引的全量数据。
2、介绍了index.max_result_window参数和相关配置方法。
3、尽管通过采用Scroll API查询索引全量数据提高了查询效率并减少了ES服务器的内存消耗。当同时要注意不要返回太大的结果集撑爆调用方应用的内存。
4、针对ES大结果集的查询,要同时考虑ES服务提供方和请求调用方的内存消耗
————————————————
版权声明:本文为CSDN博主「斗者_2013」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/w1014074794/article/details/122937401文章来源地址https://www.toymoban.com/news/detail-409890.html

到了这里,关于ES如何查询索引的全量数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Es 索引查询与删除

    1、 #删除单个索引 2、#删除多个指定索引,中间用逗号隔开 3、#模糊匹配删除 4、#使用通配符,删除所有的索引 5、#获取当前索引 6、如果存储不够可以设置定时删除,下面是保留3天的日志 以下是定时删除脚本:

    2024年02月11日
    浏览(31)
  • 【Elasticsearch】ES精确查询和范围查询,ES时间字段排序实例,ES倒排索引介绍

    termQuery matchQuery 模糊查询 multiMatchQuery 多个字段模糊查询 如果时间字段写入时用的类型是Text,可以用“时间字段.keyword”来处理 #查询前传入分页参数 #分页后拿到总记录数 把文档D对应到的映射转换为到文档ID的映射,每个都对应着一系列的文档,这些文

    2024年02月15日
    浏览(97)
  • ES查询多个索引,但是某些索引的name不同

    参考: https://blog.csdn.net/qq_37147750/article/details/111319151 背景: 目前有四个索引index, 对于这四个index他们的字段并不完全相同,要支持筛选。 目前的问题是,其中有两个索引要先根据条件筛选一遍。后续的筛选根据这次的结果做基础。 但是这两个索引的筛选条件也不一样。 相

    2024年02月13日
    浏览(32)
  • Python-ElasticSearch客户端的封装(聚合查询、统计查询、全量数据)

    官方提供了两个客户端elasticsearch、elasticsearch-dsl 第二个是对第一个的封装,类似ORM操作数据库,可以.filter、.groupby,个人感觉很鸡肋,star数也不多。平时使用的时候一般会在kibana上测试,然后直接把query拷贝过来获取更多数据,所以这里做下第一个的封装。 封装后依然暴露

    2024年02月14日
    浏览(31)
  • ES命令行查询es集群的状态、分片、索引

    查看es集群状态 查看es分片信息 查看es索引 查看ES索引 本文参考:https://www.cnblogs.com/expiator/p/14847705.html

    2024年02月12日
    浏览(34)
  • ES查询索引字段的分词结果

    一、_termvectors  1、查看文档中某一个字段的分词结果 GET /{index}/{type}/{_id}/_termvectors?fields=[field] 2、样例: text的值为:https://www.b4d99.com/html/202204/45672.html 得到的结果: 二、_analyze 1、语法 2、样例: text的值为:https://www.b4d99.com/html/202204/45672.html 得到的结果:

    2024年02月11日
    浏览(49)
  • 解决ES只能查询10000条数据的问题

    这篇文章是翻译过来的,原文在此,需要科学上网。 当查询页很深或者查询的数据量很大时,深查询就会出现。es 的自我保护机制允许的一次最大查询量是 10000 条数据。在请求中加入 trackTotalHits(true) 可以解除10000条的上限。 from size 这种实现方式有点类似于 MySQL 中的 limit。

    2024年02月12日
    浏览(23)
  • ElasticSearch---查询es集群状态、分片、索引

    查看es集群状态: 如果?后面加上pretty,能让返回的json格式化。 加上?v的返回结果,如下: 解释如下: 查看es分片信息: 查看es分片信息,模糊匹配,比如匹配test: 返回信息如下: 解析如下: 查看状态为unassigned的es分片信息: 查看es索引 查看es所有索引: indices表示索引,是

    2024年02月02日
    浏览(33)
  • 使用java来查询es索引(基于es7.8)

    1、先引入pom依赖: 2、然后在main方法里进行测试: 运行一下,打印结果跟在postman里执行出来是一样的: 后面会根据字段进行条件查询,所以在建立映射的时候,需要指定index属性为true。如下图,在postman创建映射:

    2024年02月11日
    浏览(38)
  • “更新查询超时时间“——优化ES索引更新性能的方法

    “更新查询超时时间”——优化ES索引更新性能的方法 在实际运用中,Elasticsearch (ES) 索引上的数据不可避免的需要进行更新操作。而update_by_query API 是一个十分强大的ES 更新功能工具,可以应对各种复杂的更新需求。然而,在进行高负载的大数据量操作时,update_by_query 会产生

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包