伸缩自如的ElasticSearch——通过bboss操作和访问elasticsearch模式

2023-11-08

ClientUtil

bboss操作和访问elasticsearch提供两种模式,分别对应两个组件:

  • RestClientUtil:通用组件,提供所有不依赖dsl的功能,也可以直接接收dsl。

  • ConfigRestClientUtil:加载配置文件中的dsl来实现对es的操作

这两个组件分别通过org.frameworkset.elasticsearch.ElasticSearchHelper中提供的静态工厂方法获取其单实例对象,这些单实例对象是多线程并发安全的,分别说明如下:

加载配置文件中的dsl来实现对es的操作模式

public static ClientInterface getConfigRestClientUtil(String configFile)

public static ClientInterface getConfigRestClientUtil(String elasticSearch,String configFile) //elasticsearch参数指定了bboss中多集群配

通过这两个方法获取到的ClientInterface实例是多线程安全的、单实例对象。

所有不依赖dsl的功能,或直接接收dsl模式

public static ClientInterface getRestClientUtil()

public static ClientInterface getRestClientUtil(String elasticSearch) //elasticsearch参数指定了bboss中多集群配

通过这两个方法获取到的ClientInterface实例是多线程安全的、单实例对象。

直接操作dsl使用实例:

	public void testDirectDslQuery(){
		String queryAll = "{\"query\": {\"match_all\": {}}}";
		ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
		ESDatas<Demo> esDatas =clientUtil.searchList("demo/_search",//demo为索引表,_search为检索操作action
				queryAll,//queryAll变量对应的dsl语句
				Demo.class);
		//获取结果对象列表
		List<Demo> demos = esDatas.getDatas();

		//获取总记录数
		long totalSize = esDatas.getTotalSize();
		System.out.println(totalSize);
	}

基本功能

配置es查询dsl

在resources下创建配置文件estrace/ESTracesqlMapper.xml,配置一个query dsl脚本,名称为queryServiceByCondition,我们将在后面的ClientInterface 组件中通过queryServiceByCondition引用这个脚本,脚本内容定义如下:

<properties>
   <property name="queryServiceByCondition">
        <![CDATA[
        {
            "sort": [  ##排序
                {
                    "startTime": {
                        "order": "desc"
                    }
                }
            ],
            #if($lastStartTime > 0)//search_after分页查询
            "search_after": [#[lastStartTime]],
            #end
            "size": 100, ##每次返回100条记录
            "query": {
                "bool":{
                    "filter": [
                        {"term": {  ##精确查找
                            "applicationName": #[application]
                        }}
                        #if($queryStatus.equals("success"))
                          ,
                          {"term": { ##精确查找

                               "err": 0
                          }}
                        #elseif($queryStatus.equals("error"))
                          ,
                          {"term": { ##精确查找

                               "err": 1
                          }}
                        #end
                        ,
                        {"range": { ##指定时间范围
                            "startTime": {
                                "gte": #[startTime],
                                "lt": #[endTime]
                            }
                        }}
                    ]
                    
                    #if($queryCondition && !$queryCondition.equals(""))
                     ,
                     "must" : {
                        "multi_match" : { ##分词检索,指定坐在多个field执行检索
                          "query" : #[queryCondition],

                          "fields" : [ "agentId", "applicationName" ,"endPoint","params","remoteAddr","rpc","exceptionInfo"]
                        }
                     }
                    #end
                }
            },
            "aggs": {
                "applicationsums": {
                      "terms": {
                        "field": "applicationName.keyword",##按应用名称进行统计计数
                        "size":10000
                      },
                      "aggs":{
                            "successsums" : {
                                "terms" : {
                                    "field" : "err" ##按err标识统计每个应用的成功数和失败数,0标识成功,1标识失败
                                }
                            },
                            "elapsed_ranges" : {
                                "range" : {
                                    "field" : "elapsed", ##按响应时间分段统计
                                    "keyed" : true,
                                    "ranges" : [
                                        { "key" : "1秒", "to" : 1000 },
                                        { "key" : "3秒", "from" : 1000, "to" : 3000 },
                                        { "key" : "5秒", "from" : 3000, "to" : 5000 },
                                        { "key" : "5秒以上", "from" : 5000 }
                                    ]
                                }
                            }
                      }
                }
            }
        }]]>
    </property>

</properties>

查询的java代码:

import org.frameworkset.elasticsearch.ElasticSearchHelper;
import org.frameworkset.elasticsearch.client.ClientInterface;
//加载配置文件,创建es客户端工具包
ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("estrace/ESTracesqlMapper.xml");

//构建查询条件对象
TraceExtraCriteria traceExtraCriteria = new TraceExtraCriteria();
traceExtraCriteria.setApplication("testweb88");
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
traceExtraCriteria.setStartTime(dateFormat.parse("2017-09-02 00:00:00").getTime());
traceExtraCriteria.setEndTime(dateFormat.parse("2017-09-13 00:00:00").getTime());

// 检索条件
String queryCondition = (request.getParameter("queryCondition"));
// 设置检索条件
traceExtraCriteria.setQueryCondition(queryCondition);
// 查询状态:all 全部 success 处理成功 fail 处理失败
String queryStatus = request.getParameter("queryStatus");
traceExtraCriteria.setQueryStatus(queryStatus);
//设置分页数据起点,以时间为起点
String lastStartTimeStr = request.getParameter("lastStartTime");
if(lastStartTimeStr != null && !lastStartTimeStr.equals("")) {
    Long lastStartTime = Long.parseLong(lastStartTimeStr);
    traceExtraCriteria.setLastStartTime(lastStartTime);
}

//执行查询操作,查询可以是简单的检索查询,也可以结合聚合查询
ESDatas<Traces> data //ESDatas为查询结果集对象,封装了返回的当前查询的List<Traces>结果集、符合条件的总记录数totalSize、以及聚合查询的结果
            = clientUtil.searchList("trace-*/_search",//查询操作,查询indices trace-*中符合条件的数据
                                "queryServiceByCondition",//通过名称引用配置文件中的query dsl语句
                                traceExtraCriteria,//查询条件封装对象
                                Traces.class);//指定返回的po对象类型,po对象中的属性与indices表中的文档filed名称保持一致
List<Traces> traceList = data.getDatas();//获取查询到的记过集
long totalSize = data.getTotalSize();//获取总记录数
List<Map<String, Object>> applicationsums= data.getAggregationBuckets("applicationsums");//同时可以做聚合查询,获取聚合查询结果集
for (int i = 0; i < applicationsums .size(); i++) {
			 
	Map<String, Object> map = applicationsums.get(i);
			
	//获取子聚合查询结果:成功数和失败数
	List<Map<String, Object>> appstatic = (List<Map<String, Object>>)ResultUtil.getAggBuckets(map, "successsums");
 
	//获取响应时间分段统计信息
	Map<String, Map<String, Object>> appPeriodstatic = (Map<String, Map<String, Object>>)ResultUtil.getAggBuckets(map, "elapsed_ranges");
}

这里封装条件也可以用Map替代。
比如:

 Map<String,Object> params = new HashMap<String,Object>();
		//设置applicationName1和applicationName2两个变量的值
		params.put("applicationName1","blackca\"tdemo2");
		params.put("applicationName2","blackcat\"demo3");
 ESDatas<Demo> esDatas =  //ESDatas包含当前检索的记录集合,最多1000条记录,由dsl中的size属性指定
				clientUtil.searchList("demo/_search",//demo为索引表,_search为检索操作action
						"searchWithCustomEscape",//esmapper/demo.xml中定义的dsl语句
						params,//变量参数
						Demo.class);//返回的文档封装对象类型

文档批量创建或者修改

按照日期分表:

一个完整的批量添加和修改索引文档的案例  
		//分表的时间
		SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd");
		String date = format.format(new Date());
		
		ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
		//数据1
		List<Demo> demos = new ArrayList<>();
		Demo demo = new Demo();
		demo.setDemoId(2l);
		demo.setAgentStarttime(new Date());
		demo.setApplicationName("blackcatdemo2");
		demo.setContentbody("this is content body2");
		demos.add(demo);
		//数据2
		demo = new Demo();
		demo.setDemoId(3l);
		demo.setAgentStarttime(new Date());
		demo.setApplicationName("blackcatdemo3");
		demo.setContentbody("this is content body3");
		demos.add(demo);

		//批量创建文档
		String response = clientUtil.addDateDocuments("demo",//索引表
				"demo",//索引类型
				demos);

		System.out.println("addDateDocument-------------------------");
		System.out.println(response);

		//批量更新文档
		demo.setContentbody("updated");
		response = clientUtil.updateDocuments("demo-"+date,"demo",demos);
		System.out.println("updateDateDocument-------------------------");

		System.out.println(response);
        //获取索引文档,json格式
		response = clientUtil.getDocument("demo-"+date,//索引表
				"demo",//索引类型
				"2");//文档id
		System.out.println("getDocument-------------------------");
		System.out.println(response);
        //获取索引文档,返回Demo对象类型
		demo = clientUtil.getDocument("demo-"+date,//索引表
				"demo",//索引类型
				"3",//文档id
				Demo.class);

不按日期分表:

 //一个完整的批量添加和修改索引文档的案例  
 
		ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
		List<Demo> demos = new ArrayList<>();
		Demo demo = new Demo();
		demo.setDemoId(2l);
		demo.setAgentStarttime(new Date());
		demo.setApplicationName("blackcatdemo2");
		demo.setContentbody("this is content body2");
		demos.add(demo);

		demo = new Demo();
		demo.setDemoId(3l);
		demo.setAgentStarttime(new Date());
		demo.setApplicationName("blackcatdemo3");
		demo.setContentbody("this is content body3");
		demos.add(demo);

		//批量创建文档
		String response = clientUtil.addDocuments("demo",//索引表
				"demo",//索引类型
				demos);

		System.out.println("addDocuments-------------------------");
		System.out.println(response);

		//批量更新文档
		demo.setContentbody("updated");
		response = clientUtil.updateDocuments("demo","demo",demos);
		System.out.println("updateDateDocument-------------------------");

		System.out.println(response);
        //获取索引文档,json格式
		response = clientUtil.getDocument("demo",//索引表
				"demo",//索引类型
				"2");//文档id
		System.out.println("getDocument-------------------------");
		System.out.println(response);
        //获取索引文档,返回Demo对象类型
		demo = clientUtil.getDocument("demo",//索引表
				"demo",//索引类型
				"3",//文档id
				Demo.class);

除了es能够自动生成文档_id属性,bboss提供了三种指定文档_id和parentid的方法:

  • 注解@ESId和@ESParentId
  • ClientInterface接口方法参数
  • ClientOptions(新增/修改)/UpdateOptions(修改控制)

添加索引文档时,es会自动设置文档_id属性,如果需要人工指定_id值,只需要在对象属性上设置注解@ESId即可,例如:

@ESId //ip属性作为文档唯一标识,根据ip值对应的索引文档存在与否来决定添加或者修改操作
private String ip;

@ESId同样适用于文档批量创建和修改操作

另外一个注解@ESParentId用来表示父子关系,在父子关系检索案例中有介绍。

ESId和ESParentId两个注解在添加/修改文档、批量添加/修改文档操中指定文档的_id和parent属性,如果不指定,es自动生成_id属性,parent必须手工指定。

http api

通过ClientInterface 接口提供的以下通用executeHttp api,我们可以非常方便地实现es中所有带请求报文的功能

 		ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();
        //验证环境,获取es状态
        String response = clientUtil.executeHttp("/kibana_sample_data_logs/_search", ClientInterface.HTTP_GET);
        System.out.println(response);
	public void testTempate() throws ParseException{

		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/estrace/ESTemplate.xml");
		//创建模板
		String response = clientUtil.createTempate("demotemplate_1",//模板名称
				"demoTemplate");//模板对应的脚本名称,在esmapper/estrace/ESTemplate.xml中配置
		System.out.println("createTempate-------------------------");
		System.out.println(response);
		//获取模板
		/**
		 * 指定模板
		 * /_template/demoTemplate_1
		 * /_template/demoTemplate*
		 * 所有模板 /_template
		 *
		 */
		String template = clientUtil.executeHttp("/_template/demotemplate_1",ClientUtil.HTTP_GET);
		System.out.println("HTTP_GET-------------------------");
		System.out.println(template);
		//删除模板
		template = clientUtil.executeHttp("/_template/demotemplate_1",ClientUtil.HTTP_DELETE);
		System.out.println("HTTP_DELETE-------------------------");
		System.out.println(template);

		template = clientUtil.executeHttp("/_template/demotemplate_1",ClientUtil.HTTP_GET);
		System.out.println("HTTP_GET after delete-------------------------");
		System.out.println(template);
	}

查询dsl动态脚本语法规范

bboss elasticsearch采用xml文件管理elasticsearch的dsl脚本,在dsl脚本中可以使用变量、foreach循环、逻辑判断、注释;配置文件支持在线修改、自动热加载,开发和调试非常方便。

脚本中变量定义语法有两种:#[xxx],$xxx,尽可能地在脚本中使用#[xxx]方式的变量,在#[]类型变量中还可以指定属性,后面举例说明。对于#[xxx]类型变量值中包含的可能破坏dsl json语法结构的特殊字符(例如回车换行符等),框架会自动进行转义处理;$xxx类型变量直接输出原始值(特殊字符不做转移处理),$xxx类型变量可以用于if/elseforeach循环控制变量,而#[xxx]不可以。

判断List集合datas不为空并且datas的size大于0

#if($datas && $datas.size()> 0)

#foreach($bb in $datas)

#end

#end 

  • foreach循环语法

#foreach-#end
foreach循环内置循环变量:$velocaitycount,不需要从外部传入


  • 逻辑判断语法

#if-#else-#end,#if-#elseif-#else-#end
变量值逻辑判断
#if($xxxx) ##变量值不为null判断(类似java语法 if(xxxx != null))
#end

#if(!$xxxx) ##变量值为null判断(类似java语法 if(xxxx == null))
#end

#if($xxxx && !$xxxx.equals("")) ##变量值不为null判断且不等于"“判断(类似java语法 if(xxxx != null && !xxx.equals(”")))
#end

#if($xxxx > 0) ##变量值大于某个值判断,其他类似(类似java语法 if(xxxx > 0))
#end

判断List集合不为null并且size大于0
#if($datas && $datas.size() > 0)
#end
逻辑判断还可以包含各种组合 && ||操作。


  • 在dsl中定义和修改$模式变量

定义变量
#set($needComma = true)
修改$变量值
#set($needComma = false)


  • 在dsl中使用注释

dsl注释是用多个#号来标识的,大段注释用#**#包起来
单行注释:##注释内容


  • 变量使用

#[application]
变量格式#[aaa]所有格式:
#[aaa] 简单的变量属性引用

#[aaa->bb] 如果aaa是一个bean对象,这个变量格式表示了对aaa对象的bb属性的引用,如果aaa是一个map对象,这个变量格式表示了对aaa对象的key为bb的元素值引用

#[aaa[key]] 引用map对象aaa中key所对应的value数据,引用map元素的等价方法#[aaa->key]

配置springboot

application.properties如下:

elasticsearch.rest.hostNames=localhost:9200


#动态索引表名称日期格式配置
elasticsearch.dateFormat=yyyy.MM.dd

elasticsearch.timeZone=Asia/Shanghai
elasticsearch.ttl=2d

#在控制台输出脚本调试开关showTemplate,false关闭,true打开,同时log4j至少是info级别
elasticsearch.showTemplate=false

#客户端动态发现es集群节点控制开关
elasticsearch.discoverHost=false

#http链接池配置
http.timeoutConnection = 400000
http.timeoutSocket = 400000
http.connectionRequestTimeout=400000
http.retryTime = 1
http.maxLineLength = -1
http.maxHeaderCount = 200
http.maxTotal = 400
http.defaultMaxPerRoute = 200

# dsl配置文件热加载扫描时间间隔,毫秒为单位,默认5秒扫描一次,<= 0时关闭扫描机制
dslfile.refreshInterval = -1

依赖如下:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- bboss客户端开始 -->
        <dependency>
            <groupId>com.bbossgroups.plugins</groupId>
            <artifactId>bboss-elasticsearch-spring-boot-starter</artifactId>
            <version>5.3.7</version>
        </dependency>
        <dependency>
            <groupId>com.bbossgroups.plugins</groupId>
            <artifactId>bboss-elasticsearch-rest-jdbc</artifactId>
            <version>5.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>jdbc</artifactId>
            <version>6.3.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.23.1</version>
            <scope>test</scope>
        </dependency>
        <!-- bboss客户端结束 -->

Demo地址如下:
ESDemo地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

伸缩自如的ElasticSearch——通过bboss操作和访问elasticsearch模式 的相关文章

随机推荐

  • Collectors.collectingAndThen()

    Collectors collectingAndThen Java 8 流的新类 java util stream Collectors 实现了 java util stream Collector 接口 同时又提供了大量的方法对流 str
  • 赛灵思FPGA编程入门指南

    中英双语字幕精校版 赛灵思FPGA编程入门之新手指南第1集 什么是FPGA 现场可编程门阵列 FPGA概念 什么是FPGA 现场可编程门阵列 FPGA概念 本系列视频旨在为FPGA新人逐步讲解教程和基本概念 提供FPGA编程入门指导 帮助您
  • web程序员表白程序,三行情书

    Git项目地址 loveLetter 很久之前的作品 用JS和CSS3实现的 今天给大家分享一部分 若要见完整版 请点击右侧链接下载 程序员浪漫表白 三行情书 一等奖 JS CSS3 注 这是一个3D场景 在PC端的话还可以按住鼠标左键并拖
  • 数据库-sqlserver数据库迁移到mysql

    文章目录 前言 流程 前言 有时一些sqlserver的数据库需要迁移到mysql上 流程 管理员方式启动mysql的sqlYOG图形化界面 右键对象浏览器导入外部数据库 此处点下一步没有用的 需要先建立dsn 给要建立的dsn文件起个名字
  • 申请被拒模板 (五)

    这里只是模板 仅供学习 出现任何问题 与博主无关 Hi XXXX Thank you for your interest We appreciate the time you took to apply with us At this ti
  • h2 mysql 比较_h2 数据库时间比较

    时间比较的格式是 parsedatetime imp time yyyy MM dd hh mm ss en GMT gt parsedatetime 2012 06 07 00 00 00 yyyy MM dd hh mm ss en G
  • 多态、object类、package、Integer类、String和int类型之间的转换

    多态 多态即为事物存在的多种形态 多态存在的前提 要有继承关系 要有方法的重写 父类引用指向子类对象 多态中的成员访问特点 成员变量 编译看左边 父类 运行看左边 父类 成员方法 编译看左边 父类 运行看右边 子类 静态方法 编译看左边 父
  • MySQL使用binlog日志做数据恢复

    MySQL的binlog日志是MySQL日志中非常重要的一种日志 记录了数据库所有的DML操作 通过binlog日志我们可以进行数据库的读写分离 数据增量备份以及服务器宕机时的数据恢复 定期备份固然可以在服务器发生宕机的时候快速的恢复数据
  • 使用MyJRebel获取免费的JRebel授权

    在我们开发Java Web程序的时候 调试就是一个麻烦事情 每次更改类 就需要重启服务器 对于Tomcat这样的小巧服务器来说 重启就重启吧 反正也就是几秒钟的事情 如果使用的是完整的Java EE标准服务器 GlassFish这种 重启的
  • 权威分析@RequestParam和@RequestPart 的区别(官方文档)

    一 今天写了两个文件上传的接口用到了 RequestParam和 RequestPart RequestPart 单文件上传 param file param bucket return RequestMapping uploadFile
  • Java50个关键字总结

    作业一 Java基础知识复习 一 关键字总结 1 abstract 修饰类 abstract修饰类 这个类就是抽象类 抽象类中可以有非抽象变量和成员变量 也可以有普通方法 构造方法 但是不能实例化 只能被子类继承 如果子类不是抽象类 则必须
  • python出现invalid syntax什么意思_关于Python出现invalid syntax的几种原因

    原博文 2020 03 19 16 41 1 语法错误 3 X和2 X的语法区别非常大 需要多去了解之后再下手 2 代码缩进问题 这个一般用到工具的情况下可以自动调整 3 我今天也就是傻乎乎的犯了 安装命令是在cmd下直接运行 并不是在py
  • 输入字符串型数字,将字符串型数字转化为整型数字,再将整型数字转化为字符串数字的数组,数字字符串相互转化

    输入字符串型数字 将字符串型数字转化为整型数字 再将整型数字转化为字符串数字的数组 写此函数的原因 很多题目都是对字符串的操作 特别是若能将字符串和数字相互转化 那么解题就会方便很多 直接上代码 有注释 include
  • CreateWindowEx详解

    语法 HWND CreateWindowEx DWORD dwExStyle LPCTSTR lpClassName LPCTSTR lpWindowName DWORD dwStyle int x int y int nWidth int
  • cmd命令查看笔记本电池状况

    1 以管理员身份运行 打开 命令提示符 exe 2 在命令提示符输入 powercfg batteryreport output D battery report html 其中 引号内的电池使用报告文件的保存路径可以自定义 你也可以保存到
  • linux根据进程的运行路径,停止进程

    公式 lsof grep 路径 awk print 2 xargs kill 比如我想停掉目录 home code python program 下的程序 可以使用 lsof grep home code python program aw
  • Python简介与安装

    一 windows下安装python 二 linux下安装python 三 mac系统安装python 四 学会配置不同操作系统的环境变量 windows配置环境变量 linux配置环境变量 五 写一个简单的helloworld小程序 学会
  • Python基于Zmail发送邮件

    目录 一 介绍 二 安装 三 使用须知 四 使用步骤 4 1 获得邮件授权码 以QQ邮箱为例 4 2 发送简单文本邮件 4 3 发送Html文件邮件 4 4 发送文本txt文件邮件 4 4 发送带附件邮件 4 5 验证SMTP和POP功能是
  • 了解GFS和HDFS后,要懂得分布式文件系统设计原理

    转自 https www jianshu com p fc0aa34606ce 一 概述 分布式文件系统是分布式领域的一个基础应用 其中最著名的毫无疑问是 HDFS GFS 如今该领域已经趋向于成熟 但了解它的设计要点和思想 对我们将来面临
  • 伸缩自如的ElasticSearch——通过bboss操作和访问elasticsearch模式

    文章目录 ClientUtil 加载配置文件中的dsl来实现对es的操作模式 所有不依赖dsl的功能 或直接接收dsl模式 基本功能 配置es查询dsl 文档批量创建或者修改 http api 查询dsl动态脚本语法规范 配置springb