目录
一、初始MQ
同步调用
异步调用
什么是MQ
执行下面的命令来运行MQ容器:
如果冲突了,可以先查询
RabbitMQ概述
常见消息模型
HelloWorld案例
二、SpringAMQP
引入依赖
Work Queue
消费预取限制
编辑 发布、订阅
发布订阅Fanout Exchange
发布DirectExchange
发布订阅TopicExchange
消息转化器
MQ代码
三、什么是elasticsearch
正向索引
倒排索引
文档
索引
概念对比
架构
编辑
部署单点es
1.2.加载镜像
1.3.运行
命令解释:
2.1.部署
分词器
2.2.DevTools
kibana中提供了一个DevTools界面:
3.安装IK分词器
3.1.在线安装ik插件(较慢)
3.2.离线安装ik插件(推荐)
1)查看数据卷目录
2)解压缩分词器安装包
3)上传到es容器的插件数据卷中
4)重启容器
5)测试:
3.3 扩展词词典
四、索引库操作
创建索引库
查看、删除索引库编辑
修改索引库
新增文档编辑
查看、删除文档编辑
修改文档
RestClient操作索引库
索引库代码
RestClient操作文档
操作文档代码
DSL 查询文档
DSL Query的分类编辑
DSL Query基本语法
全文检索查询编辑
精确查询编辑
地理查询编辑
相关性算分
Function Score Query编辑
复合查询 Boolean Query
搜索结果处理编辑
分页
深度分页问题
编辑高亮
RestClient查询文档
全文检索查询
精确查询 编辑
符合查询
排序和分页
高亮编辑
初始MQ
同步调用
异步调用
什么是MQ
执行下面的命令来运行MQ容器:
docker run \-e RABBITMQ_DEFAULT_USER=itcast \-e RABBITMQ_DEFAULT_PASS=123321 \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3-management
如果冲突了,可以先查询
RabbitMQ概述
常见消息模型
HelloWorld案例
SpringAMQP
引入依赖
Work Queue
消费预取限制
发布、订阅
发布订阅Fanout Exchange
发布DirectExchange
发布订阅TopicExchange
消息转化器
MQ代码
@Component
public class SpringRabbitListener {// @RabbitListener(queues = "simple.queue")
// public void listenSimpleQueue(String msg){
// System.out.println("消费者接收到simple.queue的消息:["+msg+"]");
//
// }@RabbitListener(queues = "simple.queue")public void listenWorkQueue1(String msg) throws InterruptedException {System.out.println("消费者1接收到simple.queue的消息:["+msg+"]"+ LocalTime.now());Thread.sleep(20);}@RabbitListener(queues = "simple.queue")public void listenWorkQueue2(String msg) throws InterruptedException {System.err.println("消费者2接收到simple.queue的消息:["+msg+"]"+LocalTime.now());Thread.sleep(200);}@RabbitListener(queues = "fanout.queue1")public void listenFanoutQueue1(String msg){System.out.println("消费者接收到fanout.queue1的消息:["+msg+"]");}@RabbitListener(queues = "fanout.queue2")public void listenFanoutQueue2(String msg){System.out.println("消费者接收到fanout.queue2的消息:["+msg+"]");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1"),exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),key = {"red","blue"}))public void listenDirectQueue1(String msg){System.out.println("消费者接收到direct.queue1的消息:["+msg+"]");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue2"),exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),key = {"red","yellow"}))public void listenDirectQueue2(String msg){System.out.println("消费者接收到direct.queue2的消息:["+msg+"]");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue1"),exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),key = "china.#"))public void listenTopicQueue1(String msg){System.out.println("消费者接收到topic.queue1的消息:["+msg+"]");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue2"),exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),key = "#.news"))public void listenTopicQueue2(String msg){System.out.println("消费者接收到topic.queue2的消息:["+msg+"]");}@RabbitListener(queues = "object.queue")public void listObjectQueue(Map<String,Object> msg){System.out.println("接收object.queue的消息:"+msg);}
}
@Configuration
public class FanoutConfig {//声明FanoutExchange 交换机//itcast.fanout@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("itcast.fanout");}//声明一个队列fanout.queue1@Beanpublic Queue fanoutQueue1(){return new Queue("fanout.queue1");}//绑定队列1和交换机@Beanpublic Binding fanoutBinding1(Queue fanoutQueue1,FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}//fanout.queue2//声明一个队列fanout.queue1@Beanpublic Queue fanoutQueue2(){return new Queue("fanout.queue2");}//绑定队列1和交换机@Beanpublic Binding fanoutBinding2(Queue fanoutQueue2,FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}@Beanpublic Queue objectQueue(){return new Queue("object.queue");}}
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Beanpublic MessageConverter messageConverter(){return new Jackson2JsonMessageConverter();}
}
public class PublisherTest {@Testpublic void testSendMessage() throws IOException, TimeoutException {// 1.建立连接ConnectionFactory factory = new ConnectionFactory();// 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码factory.setHost("虚拟机地址");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("itcast");factory.setPassword("123321");// 1.2.建立连接Connection connection = factory.newConnection();// 2.创建通道ChannelChannel channel = connection.createChannel();// 3.创建队列String queueName = "simple.queue";channel.queueDeclare(queueName, false, false, false, null);// 4.发送消息String message = "hello, rabbitmq!";channel.basicPublish("", queueName, null, message.getBytes());System.out.println("发送消息成功:【" + message + "】");// 5.关闭通道和连接channel.close();connection.close();}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendMessage2SimpleWueue(){String queueName = "simple.queue";String message = "hello,spring amqp!!!";rabbitTemplate.convertAndSend(queueName,message);}@Testpublic void testSendMessage2WorkQueue() throws InterruptedException {String queueName = "simple.queue";String message = "hello,message__";for ( int i = 1; i <= 50; i++ ) {rabbitTemplate.convertAndSend(queueName,message+i);Thread.sleep(20);}}@Testpublic void testSendFanoutExchange(){//交换机名称String exchangeName = "itcast.fanout";//消息String message = "hello,every one !";//发送消息rabbitTemplate.convertAndSend(exchangeName,"",message);}@Testpublic void testSendDirectExchange(){//交换机名称String exchangeName = "itcast.direct";//消息String message = "hello,blue !";//发送消息rabbitTemplate.convertAndSend(exchangeName,"red",message);}@Testpublic void testSendTopicExchange(){//交换机名称String exchangeName = "itcast.topic";//消息String message = "中国NO.1";//发送消息rabbitTemplate.convertAndSend(exchangeName,"chi.weather",message);}@Testpublic void testSendObjectExchange(){HashMap<String, Object> msg = new HashMap<>();msg.put("name","留言2");msg.put("age",21);//发送消息rabbitTemplate.convertAndSend("object.queue",msg);}}
什么是elasticsearch
正向索引
倒排索引
文档
索引
概念对比
架构
部署单点es
因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:
docker network create es-net
1.2.加载镜像
这里我们采用elasticsearch的7.12.1版本的镜像,这个镜像体积非常大,接近1G。不建议大家自己pull。
课前资料提供了镜像的tar包:
大家将其上传到虚拟机中,然后运行命令加载即可:
# 导入数据
docker load -i es.tar
同理还有kibana
的tar包也需要这样做。
1.3.运行
运行docker命令,部署单点es:
docker run -d \--name es \-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \-e "discovery.type=single-node" \-v es-data:/usr/share/elasticsearch/data \-v es-plugins:/usr/share/elasticsearch/plugins \--privileged \--network es-net \-p 9200:9200 \-p 9300:9300 \
elasticsearch:7.12.1
命令解释:
-
-e "cluster.name=es-docker-cluster"
:设置集群名称 -
-e "http.host=0.0.0.0"
:监听的地址,可以外网访问 -
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m"
:内存大小 -
-e "discovery.type=single-node"
:非集群模式 -
-v es-data:/usr/share/elasticsearch/data
:挂载逻辑卷,绑定es的数据目录 -
-v es-logs:/usr/share/elasticsearch/logs
:挂载逻辑卷,绑定es的日志目录 -
-v es-plugins:/usr/share/elasticsearch/plugins
:挂载逻辑卷,绑定es的插件目录 -
--privileged
:授予逻辑卷访问权 -
--network es-net
:加入一个名为es-net的网络中 -
-p 9200:9200
:端口映射配置
在浏览器中输入:http://192.168.150.101:9200 即可看到elasticsearch的响应结果:
kibana可以给我们提供一个elasticsearch的可视化界面,便于我们学习。
2.1.部署
运行docker命令,部署kibana(版本一定要一样)
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
-
--network es-net
:加入一个名为es-net的网络中,与elasticsearch在同一个网络中 -
-e ELASTICSEARCH_HOSTS=http://es:9200"
:设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch -
-p 5601:5601
:端口映射配置
kibana启动一般比较慢,需要多等待一会,可以通过命令:
docker logs -f kibana
查看运行日志,当查看到下面的日志,说明成功:
分词器
2.2.DevTools
kibana中提供了一个DevTools界面:
这个界面中可以编写DSL来操作elasticsearch。并且对DSL语句有自动补全功能。
3.安装IK分词器
3.1.在线安装ik插件(较慢)
# 进入容器内部
docker exec -it elasticsearch /bin/bash# 在线下载并安装
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip#退出
exit
#重启容器
docker restart elasticsearch
3.2.离线安装ik插件(推荐)
1)查看数据卷目录
安装插件需要知道elasticsearch的plugins目录位置,而我们用了数据卷挂载,因此需要查看elasticsearch的数据卷目录,通过下面命令查看:
docker volume inspect es-plugins
显示结果:
[{"CreatedAt": "2022-05-06T10:06:34+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/es-plugins/_data","Name": "es-plugins","Options": null,"Scope": "local"}
]
说明plugins目录被挂载到了:/var/lib/docker/volumes/es-plugins/_data
这个目录中。
2)解压缩分词器安装包
下面我们需要把课前资料中的ik分词器解压缩,重命名为ik
3)上传到es容器的插件数据卷中
4)重启容器
# 4、重启容器
docker restart es
# 查看es日志
docker logs -f es
5)测试:
IK分词器包含两种模式:
-
ik_smart
:最少切分 -
ik_max_word
:最细切分
GET /_analyze
{"analyzer": "ik_max_word","text": "我爱学习java太棒了"
}
结果:
{"tokens" : [{"token" : "我","start_offset" : 0,"end_offset" : 1,"type" : "CN_CHAR","position" : 0},{"token" : "爱学习","start_offset" : 1,"end_offset" : 4,"type" : "CN_WORD","position" : 1},{"token" : "学习","start_offset" : 2,"end_offset" : 4,"type" : "CN_WORD","position" : 2},{"token" : "java","start_offset" : 4,"end_offset" : 8,"type" : "ENGLISH","position" : 3},{"token" : "太棒了","start_offset" : 8,"end_offset" : 11,"type" : "CN_WORD","position" : 4},{"token" : "太棒","start_offset" : 8,"end_offset" : 10,"type" : "CN_WORD","position" : 5},{"token" : "了","start_offset" : 10,"end_offset" : 11,"type" : "CN_CHAR","position" : 6}]
}
3.3 扩展词词典
随着互联网的发展,“造词运动”也越发的频繁。出现了很多新的词语,在原有的词汇列表中并不存在。比如:“奥力给”,“传智播客” 等。
所以我们的词汇也需要不断的更新,IK分词器提供了扩展词汇的功能。
1)打开IK分词器config目录:
2)在IKAnalyzer.cfg.xml配置文件内容添加:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties><comment>IK Analyzer 扩展配置</comment><!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典--><entry key="ext_dict">ext.dic</entry>
</properties>
索引库操作
创建索引库
#创建索引库
PUT /heihei
{"mappings": {"properties": {"info": {"type": "text","analyzer": "ik_smart"},"email": {"type": "keyword","index": false},"name": {"type": "object","properties": {"firstName": {"type": "keyword"},"lastName": {"type": "keyword"}}}}}
}
查看、删除索引库
修改索引库
新增文档
查看、删除文档
修改文档
RestClient操作索引库
#酒店的mapping
PUT /hotel
{"mappings": {"properties": {"id":{"type": "keyword"},"name":{"type": "text","analyzer": "ik_max_word"},"adress":{"type": "keyword","index": false},"price":{"type": "integer"},"score":{"type": "integer"},"brand":{"type": "keyword"},"city":{"type": "keyword"},"starName":{"type": "keyword"},"business":{"type": "keyword"},"location":{"type": "geo_point"},"pic":{"type": "keyword","index": false}}}
}
索引库代码
public class HotelIndexTest {private RestHighLevelClient client;@Testvoid testInit(){System.out.println(client);}@Testvoid createHotelIndex() throws IOException {//1.创建Request对象CreateIndexRequest request = new CreateIndexRequest("hotel");//2.准备请求的参数,DSL语句request.source(MAPPTING_TEMPLATE, XContentType.JSON);//3.发送请求client.indices().create(request, RequestOptions.DEFAULT);}@Testvoid deleteHotelIndex() throws IOException {//1.创建Request对象DeleteIndexRequest request = new DeleteIndexRequest("hotel");//3.发送请求client.indices().delete(request, RequestOptions.DEFAULT);}@Testvoid testExistHotelIndex() throws IOException {//1.创建Request对象GetIndexRequest request = new GetIndexRequest("hotel");boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);//3.发送请求System.err.println(exists ? "索引库已经存在" : "索引库不存在!");}@BeforeEachvoid setUp(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")));}@AfterEachvoid tearDown()throws IOException{this.client.close();}
}
RestClient操作文档
操作文档代码
@SpringBootTest
public class HotelDocumentTest {@Autowiredprivate IHotelService hotelService;private RestHighLevelClient client;@Testvoid testAddDcoument() throws IOException {//根据id查询酒店数据Hotel hotel = hotelService.getById(36934L);//转化为文档类型HotelDoc hotelDoc = new HotelDoc(hotel);//1.准备Request对象IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());//2.准备Json文件request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);client.index(request,RequestOptions.DEFAULT);//3.发送请求}@Testvoid testGetDocumentById() throws IOException {//1.准备RequestGetRequest request = new GetRequest("hotel", "36934");//2.发送请求,得到响应GetResponse response = client.get(request, RequestOptions.DEFAULT);//3.解析响应结果String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);}@Testvoid testRulkRequest() throws IOException {//批量查询酒店数据List<Hotel> hotels = hotelService.list();//1.创建RequestBulkRequest request = new BulkRequest();//2.准备参数,添加多个新增的Requestfor ( Hotel hotel : hotels ) {//转换为文档类型HotelDocHotelDoc hotelDoc = new HotelDoc(hotel);//2.准备参数,添加多个新增的Requestrequest.add(new IndexRequest("hotel").id(hotel.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));}//3.发送请求client.bulk(request,RequestOptions.DEFAULT);}@Testvoid testUpdateDocumentById() throws IOException {//1.准备RequestUpdateRequest request = new UpdateRequest("hotel", "36934");//2.准备请求参数request.doc("price","952","starName","五钻");//2.发送请求,得到响应client.update(request, RequestOptions.DEFAULT);//3.解析响应结果}@Testvoid testDeleteDocumentById() throws IOException {List<Hotel> list = hotelService.list();//循环删除for ( Hotel hotel : list ) {//1.准备RequestDeleteRequest request = new DeleteRequest("hotel", hotel.getId().toString());//2.发送请求,得到响应client.delete(request, RequestOptions.DEFAULT);}//1.准备RequestDeleteRequest request = new DeleteRequest("hotel", "36934");//2.发送请求,得到响应client.delete(request, RequestOptions.DEFAULT);}@BeforeEachvoid setUp(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://虚机机地址:es端口")));}@AfterEachvoid tearDown()throws IOException{this.client.close();}
}
DSL 查询文档
DSL Query的分类
DSL Query基本语法
全文检索查询
GET /hotel/_doc/36934#查询所有
GET /hotel/_search
{"query": {"match_all": {}}
}#math查询
GET /hotel/_search
{"query": {"match": {"all": "外滩如家"}}
}#multi_math查询
GET /hotel/_search
{"query": {"multi_match": {"query": "外滩如家","fields": ["brand","name","business"]}}
}
精确查询
#term查询
GET /hotel/_search
{"query": {"term": {"city": {"value": "上海"}}}
}#range查询 几个e代表等于
GET /hotel/_search
{"query": {"range": {"price": {"gte": 1000,"lte": 3000}}}
}
地理查询
#distance查询
GET /hotel/_search
{"query": {"geo_distance": {"distance":"3km","location":"31.219306, 121.445427"}}
}
相关性算分
Function Score Query
#function score 查询
GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"all": "外滩"}},"functions": [{"filter":{"term":{"brand":"7天酒店"}},"weight":10}],"boost_mode":"sum"}}}}
}
复合查询 Boolean Query
GET /hotel/_search
{"query": {"bool": {"must": [{"match": {"name": "如家"}}],"must_not": [{"range": {"price": {"gt": 400}}}],"filter": [{"geo_distance": {"distance": "10km","location": {"lat": 31.21,"lon": 121.5}}}]}}
}
搜索结果处理
排序
#sort排序
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": "desc"},{"price": "asc" }]
}#找到121.6122,31.034周围的酒店,距离升序排序
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 31.034,"lon": 121.6122},"order": "asc","unit": "km"}}]
}
分页
深度分页问题
高亮
#分页查询
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"price": "asc" }],"from":10,"size":10
}#高亮显示 默认情况,ES搜索字段必须与高亮字段一致
GET /hotel/_search
{"query": {"match": {"all": "如家"}},"highlight": {"fields": {"name":{"require_field_match": "false"}}}
}
RestClient查询文档
全文检索查询
精确查询
符合查询
排序和分页
高亮
觉得好的小伙伴记得一键三连哦
public class HotelIsearchTest {private RestHighLevelClient client;@Testvoid testMatchAll() throws IOException {//1 准备RequestSearchRequest request = new SearchRequest("hotel");//2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4解析响应handleRequest(response);}/*** 全文检索查询* @throws IOException*/@Testvoid testMatch() throws IOException {//1 准备RequestSearchRequest request = new SearchRequest("hotel");//2.准备DSLrequest.source().query(QueryBuilders.matchQuery("all","如家"));//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleRequest(response);}/*** 精确查询、复合查询* @throws IOException*/@Testvoid testBool() throws IOException {//1 准备RequestSearchRequest request = new SearchRequest("hotel");//2.准备DSL//2.1准备BooleanQueryBoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//2.2添加termboolQuery.must(QueryBuilders.termQuery("city","上海"));//2.3添加rangeboolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));request.source().query(boolQuery);//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleRequest(response);}/*** 排序和分页* @throws IOException*/@Testvoid testPageAndSort() throws IOException {//页码、每页大小int page = 2,size = 5;//1 准备RequestSearchRequest request = new SearchRequest("hotel");//2.准备DSL//2.1queryrequest.source().query(QueryBuilders.matchAllQuery());//2.2排序sortrequest.source().sort("price", SortOrder.ASC);//2.3分页from、sizerequest.source().from((page-1) * size).size(5);//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleRequest(response);}/*** 高亮* @throws IOException*/@Testvoid testHighlight() throws IOException {//1 准备RequestSearchRequest request = new SearchRequest("hotel");//2.准备DSL//2.1queryrequest.source().query(QueryBuilders.matchQuery("all","如家"));//2.2高亮request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);handleHighlight(response);}private void handleRequest(SearchResponse response) {//4解析响应SearchHits searchHits = response.getHits();//4.1 获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");//4.2文档数组SearchHit[] hits = searchHits.getHits();//4.3遍历for ( SearchHit hit : hits ) {//获取文档sourceString json = hit.getSourceAsString();//反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println("hotelDoc = " + hotelDoc);}System.out.println(response);}/*** 高亮结果分析* @param response*/private void handleHighlight(SearchResponse response) {//4解析响应SearchHits searchHits = response.getHits();//4.1 获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");//4.2文档数组SearchHit[] hits = searchHits.getHits();//4.3遍历for ( SearchHit hit : hits ) {//获取文档sourceString json = hit.getSourceAsString();//反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);//获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();if ( !CollectionUtils.isEmpty(highlightFields) ) {//根据字段名获取如果HighlightField highlightField = highlightFields.get("name");if ( highlightField!=null ) {//获取高亮的值String name = highlightField.getFragments()[0].string();//覆盖非高亮结果hotelDoc.setName(name);}}System.out.println("hotelDoc = " + hotelDoc);}System.out.println(response);}/*** 高亮结果解析*/@BeforeEachvoid setUp(){this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")));}@AfterEachvoid tearDown()throws IOException{this.client.close();}
}