草庐IT

easy-es的出现,江湖不再需要RestHighLevelClient

强哥叨逼叨 2023-04-05 原文

点击关注强哥,查看更多精彩文章呀

 

哈喽,大家好,我是强哥。

当今天下,ES(ElasticSearch)作为搜索服务界的扛把子,凭借其分布式、高扩展、高实时的搜索与数据分析能力,备受程序员小屁民的追捧。而ES在稳坐老大位置的同时,将Kibana和Logstash收为麾下,成立帮会:ELK,成为江湖上赫赫有名的第一大帮。

然而,随着时间的慢慢流逝,帮主ES的一些霸道手段也慢慢展露出来。

雄霸一方,欺压百姓

在江湖之上,码农们要用到搜索引擎的服务,就必须和帮主ES交易,而ES性格怪诞,定下号令,想要与他交易的,必须使用他自创的DSL语法。而就是学习这一语法让码农们痛苦不堪。

码农们师从一派,自幼受SQL语法的熏陶,由于往日与其他帮派交易也都多以SQL方式,大家往来甚是融洽。而唯独与这ELK帮交易最为难受,其蹩脚难懂的DSL语法让码农们苦不堪言。而搜索服务又往往是日常生活中或多或少要用的上的,于是乎,江湖上开始怨声载道。

而ES显然也注意到了这点,也有搞出xpack等工具来“帮助”大家。可是,这玩意更是暴露了其贪婪的特性。xpack的使用采用类似租赁制,码农们想要使用,就要交钱。这明显的就是对穷困潦倒的码农们的一种嘲讽。

码农们也是敢怒而不敢言,搜索服务不得不用,谁让ES一家独大,DSL难用也得学啊,总比什么都没有强。

风云再起,救星降临

要问当下,码农们与数据库第一大帮Mysql交易最为密切,彼此交易使用SQl语法来进行通信,智者更是创造了Mybatis-Plus工具使码农们与Mysql交易起来更为便捷快速。

而一提到要和ES交易,人们就愁容满面,每次交易前,都需带上一大本工具书,仔细查阅一番后,才能顺利生成DSL语法进行交易。

随着时间的流逝,越来越多的有志之士开始另辟蹊径,而一个工具的诞生,也打破了江湖多年的沉寂。

这个工具,就是easy-es

博采众长,备受追捧

要说发明这个工具的智者,也是师出Mybatis-Plus,同时对ES DSL语法的研究也是极为深入。

他在DSL语法之上,对照Mybatis-Plus的功能,造出了一个能与ES交易的ES版Mybatis-Plus,起名easy-es

工具使用起来也极为简单。我们可以拿它与DSL的RestHighLevelClient(码农们原来生成DSL语法的工具)对比一下。

需求:查询出文档标题为 "中国功夫"且作者为"老汉"的所有文档

使用Easy-Es仅需3行代码即可完成查询:

LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, "中国功夫").eq(Document::getCreator, "老汉");
List<Document> documents = documentMapper.selectList(wrapper);

传统方式, 直接用RestHighLevelClient进行查询:

// 传统方式, 直接用RestHighLevelClient进行查询 需要11行代码,还不包含解析JSON代码
String indexName = "document";
SearchRequest searchRequest = new SearchRequest(indexName);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermQueryBuilder titleTerm = QueryBuilders.termQuery("title", "中国功夫");
TermsQueryBuilder creatorTerm = QueryBuilders.termsQuery("creator", "老汉");
boolQueryBuilder.must(titleTerm);
boolQueryBuilder.must(creatorTerm);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
try {
 SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
 // 然后从searchResponse中通过各种方式解析出DocumentList 省略这些代码...
} catch (IOException e) {
    e.printStackTrace();
}

可以看出,上面一个简单的查询演示,在代码量上就有了很大的差别。实际使用场景越复杂,效果就越好,平均可节省3-5倍代码量。

当然,ES经常被作为大数据量的准实时查询,那么,使用了easy-es之后,对查询的性能会不会有所影响呢?毕竟,这个工作是在传统工具上的再创作。

我们先来看easy-es在整个查询过程中做了什么事? 总结起来就2件:

  1. 把用户输入的MySQL语法(Mybatis-Plus语法)转换成RestHighLevel语法,然后调用RestHighLevelClient执行本次查询

  2. 把查询结果转换成用户想要的格式:如List并返回.

  • 其中,语法转换是按照MySQL和RestHighLevelClient语法对照表的关系进行转换.这种转换其实耗费的性能非常低,因为即使你直接使用RestHighLevelClient进行查询,你依旧需要创建出termQueryBuilder和BoolQueryBuilder. 唯一的区别就是我把用户输入的查询条件eq放入了队列,然后通过队里FIFO(除查询条件中有or的情况)的顺序逐一进行转换,对于绝大多数查询语句,查询条件都不会太多,所以队里中的元素数大多数情况下都会小于10,而且队列中我只存了枚举和参数,既不会占用过多内存,也不会因为队列的遍历消耗多少性能. 对于现代计算机而言,别说遍历10条小数据,就是成百上千条也是毫秒级的,所以这点性能损耗基本可以忽略不计。

  • 再说结果解析,结果解析其实就是把调用RestHighLevelClient返回的SearchResponse中的hits取出并用fastJson转换成数组,这个过程就算不用EE,你直接用RestHighLevelClient也是会有这一步,所以这一步并没有过多的损耗,即便是我用了反射,字段的反射和注解信息,都在框架启动时加载进内存中了,做了jvm的缓存,所以这点损耗可忽略不计。

当然如上都是基于理论分析,在0.9.6版本中,Sample模块的test目录Performance测试类中,大家可以看到我针对CURD分别作了不同维度的性能测试,实际测试的结果也很好的印证了我上面的理论分析,EE除了查询会比直接使用RestHighLevelClient平均慢10-15毫秒,增删改API并无差异,而且随着查询数据量的增大,实体字段缓存生效后,查询差异会进一步降低,几乎可以忽略不计. 牺牲10毫秒,对用户而言是无感知的,但对开发而言,可以节省大量代码和时间,我认为这是值得的,基本上没有哪款ORM框架是不会损耗性能的,权衡利弊,主公们心理应该都会有答案.

智者还保证,只要使用工具除了问题,都会积极的耐心解答。

由此可见,码农们接入easy-es,可谓优势多多:

  • 简单易用高效不用我多说了吧,MyBatis-Plus用户懂的都懂! 大把的时间节省出来,做...爱做的事情,真香!

  • 使用门槛降低,就算是刚不懂Es的小白,也可以用EE开发各种功能

  • 大幅减少代码量,提升代码可读性,降低重复代码量,提升代码质量

  • 专业答疑团队,无忧售后

  • 永久免费

easy-es工具附录

项目地址:https://gitee.com/dromara/easy-es

文档地址:https://easy-es.cn/#/README

点击关注强哥,查看更多精彩文章呀

有关easy-es的出现,江湖不再需要RestHighLevelClient的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  3. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  4. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  5. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  8. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  9. ruby - 我需要从 facebook 游戏中抓取数据——使用 ruby - 2

    修改(澄清问题)我已经花了几天时间试图弄清楚如何从Facebook游戏中抓取特定信息;但是,我遇到了一堵又一堵砖墙。据我所知,主要问题如下。我可以使用Chrome的检查元素工具手动查找我需要的html-它似乎位于iframe中。但是,当我尝试抓取该iframe时,它​​是空的(属性除外):如果我使用浏览器的“查看页面源代码”工具,这与我看到的输出相同。我不明白为什么我看不到iframe中的数据。答案不是它是由AJAX之后添加的。(我知道这既是因为“查看页面源代码”可以读取Ajax添加的数据,也是因为我有b/c我一直等到我可以看到数据页面之后才抓取它,但它仍然不存在)。发生这种情况是因为

  10. ruby - 需要重构为新的 Ruby 1.9 哈希语法 - 2

    这个问题在这里已经有了答案:HashsyntaxinRuby[duplicate](1个回答)关闭5年前。我有一个Recipe,其中包含以下未通过lint测试的代码:service'apache'dosupports:status=>true,:restart=>true,:reload=>trueend失败并出现错误:UsethenewRuby1.9hashsyntax.supports:status=>true,:restart=>true,:reload=>true不确定新语法是什么样的...有人可以帮忙吗?

随机推荐