我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ES中的三种查询

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ES中的三种查询

Es有三种查询方式,不知道你平时工作中用到的是哪种呢?
一、from+Size
1、深度分页或者size特别大的时候,会出现deep pagination问题.并且因为Es自身的保护机制(max_result_window是10000),如果查出来的数据量大于10000的就会报错.
2、该查询的实际原理类似于mysql中的limit,比如查询第10001条数据,那么需要将前面的10000条都拿出来,进行过滤,最终才得到数据(性能比较差,实现简单,适用于少量数据).

二、scroll
1、高效进行滚动查询,首次查询会在内存中保存一个历史快照以及游标(scroll_id),记录当前消息查询的终止位置,下次查询的时候将基于游标进行消费(性能良好,不具备实施性,一般是用于大量数据导出或索引重建)
2、可以查询10000条以上数据.
3、当使用完查询的数据之后,记得要手动清理,因为scroll查询会生成快照,虽然会有过期时间,但是如果并发访问量激增的时候,都没达到过期时间,就会导致内存溢出.

三、search after
1、缺点是不能够随机跳转分页,只能是一页一页的向后翻(当有新数据进来,也能实时查询到),并且需要至少指定一个唯一不重复字段来排序(一般是_id)
2、当使用search_after时,from值必须设置为0或者-1
3、可以查询10000条以上数据.

from+size demo

QueryBuilder query = new QueryBuilder();SearchRequest searchRequest = new SearchRequest(index);        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()        // 分页参数            .from(page.getPage())            .size(page.getSize())            .trackTotalHits(true)            // 过滤条件            .query(query);        if (sort != null) {        // 排序            searchSourceBuilder.sort(sort.getSortFiled(), sort.getSortOrder());            searchSourceBuilder.sort("_id", SortOrder.DESC);        }        if (fields != null) {        // 查询的结果字段            searchSourceBuilder.fetchSource(fields, null);        }        searchRequest.source(searchSourceBuilder);        try {        // 进行查询            SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);            SearchHits searchHits = searchResponse.getHits();            if (searchHits == null) {                return EsResult.EMPTY;            }            // 结果转换,clazz是对应的DTO            List<T> data = covert2JavaBeanList(searchHits.getHits(), clazz);            return new EsResult<>(NumberUtils.toInt(String.valueOf(searchHits.getTotalHits().value)), data);        } catch (IOException e) {            EsExceptionUtil.dealIOException(e);        } catch (ElasticsearchException e1) {            EsExceptionUtil.dealElasticsearchException(e1);        }        return EsResult.EMPTY;

scroll demo

// 设置过期时间Scroll scroll = new Scroll(TimeValue.timeValueMinutes(30));SearchResponse searchResponse = null;        if (StringUtils.isEmpty(scrollId)) {            // 1.构建SearchRequest检索请求            // 专门用来进行全文检索、关键字检索的API            SearchRequest searchRequest = new SearchRequest(index);            // 2.创建一个SearchSourceBuilder专门用于构建查询条件            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()                .trackTotalHits(true)                .query(query);            if (CollectionUtils.isNotEmpty(sorts)) {                for (EsSort sort : sorts) {// 排序字段                                        searchSourceBuilder.sort(sort.getSortFiled(), sort.getSortOrder());                }            }            if (fields != null) {                searchSourceBuilder.fetchSource(fields, null);            }            // 每页显示多少条            searchSourceBuilder.size(pageSize);            // 4.调用SearchRequest.source将查询条件设置到检索请求            searchRequest.source(searchSourceBuilder);            //--------------------------            // 设置scroll查询            //--------------------------            searchRequest.scroll(scroll);            try {                searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);                return gettEsScrollResult(clazz, searchResponse);            } catch (IOException e) {                EsExceptionUtil.dealIOException(e);            } catch (ElasticsearchException e1) {                EsExceptionUtil.dealElasticsearchException(e1);            }        }        // 第二次查询的时候,直接通过scroll id查询数据        else {            SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);            searchScrollRequest.scroll(scroll);            // 使用RestHighLevelClient发送scroll请求            try {                searchResponse = restClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);                return gettEsScrollResult(clazz, searchResponse);            } catch (IOException e) {                EsExceptionUtil.dealIOException(e);            } catch (ElasticsearchException e1) {                EsExceptionUtil.dealElasticsearchException(e1);            }        }        SearchHits searchHits;        List<T> data = Lists.newArrayList();        if (searchResponse != null) {            searchHits = searchResponse.getHits();            data = covert2JavaBeanList(searchHits.getHits(), clazz);        } else {            searchHits = SearchHits.empty();        }        return new EsScrollResult<>(NumberUtils.toInt(String.valueOf(searchHits.getTotalHits().value)), searchResponse != null ? searchResponse.getScrollId() : "", data);

手动清理scroll demo

public void clearScroll(List<String> scrollIds) {        if (CollectionUtils.isEmpty(scrollIds)) {            return;        }        List<String> notEmptyIds = scrollIds.stream().filter(o -> !StringUtils.EMPTY.equals(o)).collect(Collectors.toList());        if (CollectionUtils.isEmpty(notEmptyIds)) {            return;        }        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();        notEmptyIds.forEach(clearScrollRequest::addScrollId);        try {            ClearScrollResponse clearScrollResponse = restClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);            log.info("清理scrollId:{},状态:{},释放空间:{}", notEmptyIds, clearScrollResponse.isSucceeded(), clearScrollResponse.getNumFreed());        } catch (IOException e) {            log.warn("清理scroll失败", e);        }    }

search after demo

SearchRequest searchRequest = new SearchRequest(index);        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()            .query(query)            .fetchSource(fields, null)            .trackTotalHits(true)            .size(pageSize);            // 判断是否是第一次查询        if (sortValues != null && sortValues.length != 0) {            searchSourceBuilder.searchAfter(sortValues);        }        boolean idSort = false;        if (CollectionUtils.isNotEmpty(sorts)) {            for (EsSort sort : sorts) {                searchSourceBuilder.sort(sort.getSortFiled(), sort.getSortOrder());        // 保证有唯一的排序字段                if ("_id".equals(sort.getSortFiled())) {                    idSort = true;                }            }        }        if (!idSort) {            throw new EsDataException("排序参数必须包含_id");        }        searchRequest.source(searchSourceBuilder);        try {            SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);            if (searchResponse.getHits() == null || searchResponse.getHits().getHits().length == 0) {                return EsSearchAfterResult.EMPTY;            }            SearchHit[] searchHits = searchResponse.getHits().getHits();            List<T> data = covert2JavaBeanList(searchHits, clazz);            // 取出最后一条记录的位置            SearchHit lastHit = searchHits[searchHits.length - 1];      // 得到最后一条记录的sortValue值,返回给调用方,让调用方作为下一页查询的条件            Object[] lastSortValues = lastHit.getSortValues();            return new EsSearchAfterResult<>(NumberUtils.toInt(String.valueOf(searchResponse.getHits().getTotalHits().value)), data, lastSortValues);        } catch (IOException e) {            EsExceptionUtil.dealIOException(e);        } catch (ElasticsearchException e1) {            EsExceptionUtil.dealElasticsearchException(e1);        }        return EsSearchAfterResult.EMPTY;

总结:
1、from + size的大小和es的保护机制的大小要一致,否则会报错
2、使用scroll的时候一定要记得要记得手动清理掉缓存
3、searchAfter 一定要设置唯一的排序字段,否则可能导致数据查询的少.

来源地址:https://blog.csdn.net/qq_40708942/article/details/127427004

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ES中的三种查询

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

mysql去重查询的三种方法

文章目录 前言一、插入测试数据二、剔除重复数据方法1.方法一:使用distinct2.方法二:使用group by3.方法三:使用开窗函数 总结 前言 数据库生成环境中经常会遇到表中有重复的数据,或者进行关联过程中产生重复
2023-08-16

gitlab权限查询的三种方法

在使用GitLab进行版本管理和代码协作的过程中,权限管理是非常重要的。不同的用户或用户组需要不同的权限,以确保代码的安全性和合规性。在GitLab中,可以通过多种方式来查询权限,本文将简单介绍其中几种方式。通过Web界面查询权限GitLa
2023-10-22

在es中查询null值的操作方法

在我们向es中写入数据时,有些时候数据写入到es中的是null,或者没有写入这个字段,那么这个时候在es中该如何查询出这种为null的数据呢,本文给大家详细讲解,需要的朋友参考下吧
2023-02-01

Mybatis模糊查询Like的三种方式

在实际项目中,我们会经常对数据做一些模糊查询的操作,这时候就需要利用到 like 字段,那么在Mybatis中,有哪些方式可以实现模糊查询呢?这里就简单的介绍下:Mybatis模糊查询Like的三种方式,如果对你有帮助,码文不易,请一键
2023-08-30

mybatis-plus分页查询三种方法

mybatis-plus分页查询 一、前期准备表1、配置类 二、使用selectPage1、Service2、结果 三、使用2种分页查询的写法1、xml2、Mapper3、第一种写法4、第一种结果5、第二种写法6、第二种结果
2023-08-20

es怎么实现mysql的like查询

在MySQL中,可以使用LIKE操作符实现模糊查询。LIKE操作符用于在WHERE子句中搜索指定模式的数据,可以使用通配符来匹配任意字符或任意数量的字符。通配符有两种:百分号(%):表示任意字符的任意数量。下划线(_):表示单个字符。例
es怎么实现mysql的like查询
2024-04-18

MySQL 重写查询语句的三种策略

在优化存在问题的查询时,我们需要改变方式去获取查询结果——但这并不意味着从 MySQL获取同样的结果集。有些时候我们可以将查询转换为获取相同结果,但更好性能的查询形式。然而,我们也需要考虑重写查询去获取不同的结果,因为这样可以提高开发效率。
2022-05-23

sql跨表查询的三种方案总结

目录前言方案一:连接多个库,同步执行查询优点缺点代码执行方案二:在主数据库增加冗余表,通过定时更新cLdNwV,造成同库联表查询优点缺点相似实现场景方案三:dbLink本地连接多个库,在本地进行数据分析优点缺点前言最近又个朋友问我,如何进
2022-08-11

sqlServer实现分页查询的三种方式

目录一、offset /fetch next关键字二、利用max(主键)三、利用row_number关键字总结sqlServer的分页查询和mysql语句不一样,有三种实现方式。分别是:offset /fetch next、利用max(主键
2023-03-02

SQL Server中查询最近一条记录的三种方法

目录引言方法一:使用ORDER BY子句和TOP子句方法二:使用MAX函数和子查询方法三:使android用ROW_NUMBER函数总结引言在使用SQL Server数据库时,有时我们需要查询表中的最近一条记录。这可能涉及到查找表中的最新
SQL Server中查询最近一条记录的三种方法
2024-09-18

java使用es查询的示例代码

众所周知,elasticsearch简称es,它是基于基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放
2023-05-30

kibana怎么查询es的索引数据量

要查询Elasticsearch索引的数据量,可以使用Kibana的Dev Tools或者Console工具来执行查询。以下是使用Kibana的Dev Tools进行索引数据量查询的步骤:1. 打开Kibana的Dev Tools界面。2.
2023-10-09

es怎么查询所有索引的名称

在Elasticsearch中,您可以使用以下命令查询所有索引的名称:GET /_cat/indices?v这将返回一个包含所有索引名称的列表,其中包括索引的相关信息,如存储大小、文档计数等。如果您正在使用Elasticsearch的
2023-10-24

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录