目录
一、初始MQ
四、索引库操作
初始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
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("itcast.fanout");
}
//声明一个队列fanout.queue1
@Bean
public Queue fanoutQueue1(){
return new Queue("fanout.queue1");
}
//绑定队列1和交换机
@Bean
public Binding fanoutBinding1(Queue fanoutQueue1,FanoutExchange fanoutExchange){
return BindingBuilder
.bind(fanoutQueue1)
.to(fanoutExchange);
}
//fanout.queue2
//声明一个队列fanout.queue1
@Bean
public Queue fanoutQueue2(){
return new Queue("fanout.queue2");
}
//绑定队列1和交换机
@Bean
public Binding fanoutBinding2(Queue fanoutQueue2,FanoutExchange fanoutExchange){
return BindingBuilder
.bind(fanoutQueue2)
.to(fanoutExchange);
}
@Bean
public Queue objectQueue(){
return new Queue("object.queue");
}
}
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
public class PublisherTest {
@Test
public 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.创建通道Channel
Channel 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 {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSendMessage2SimpleWueue(){
String queueName = "simple.queue";
String message = "hello,spring amqp!!!";
rabbitTemplate.convertAndSend(queueName,message);
}
@Test
public 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);
}
}
@Test
public void testSendFanoutExchange(){
//交换机名称
String exchangeName = "itcast.fanout";
//消息
String message = "hello,every one !";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"",message);
}
@Test
public void testSendDirectExchange(){
//交换机名称
String exchangeName = "itcast.direct";
//消息
String message = "hello,blue !";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"red",message);
}
@Test
public void testSendTopicExchange(){
//交换机名称
String exchangeName = "itcast.topic";
//消息
String message = "中国NO.1";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"chi.weather",message);
}
@Test
public 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;
@Test
void testInit(){
System.out.println(client);
}
@Test
void 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);
}
@Test
void deleteHotelIndex() throws IOException {
//1.创建Request对象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
//3.发送请求
client.indices().delete(request, RequestOptions.DEFAULT);
}
@Test
void testExistHotelIndex() throws IOException {
//1.创建Request对象
GetIndexRequest request = new GetIndexRequest("hotel");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
//3.发送请求
System.err.println(exists ? "索引库已经存在" : "索引库不存在!");
}
@BeforeEach
void setUp(){
this.client = new RestHighLevelClient(
RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")
));
}
@AfterEach
void tearDown()throws IOException{
this.client.close();
}
}
RestClient操作文档
操作文档代码
@SpringBootTest
public class HotelDocumentTest {
@Autowired
private IHotelService hotelService;
private RestHighLevelClient client;
@Test
void 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.发送请求
}
@Test
void testGetDocumentById() throws IOException {
//1.准备Request
GetRequest 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);
}
@Test
void testRulkRequest() throws IOException {
//批量查询酒店数据
List<Hotel> hotels = hotelService.list();
//1.创建Request
BulkRequest request = new BulkRequest();
//2.准备参数,添加多个新增的Request
for ( Hotel hotel : hotels ) {
//转换为文档类型HotelDoc
HotelDoc hotelDoc = new HotelDoc(hotel);
//2.准备参数,添加多个新增的Request
request.add(new IndexRequest("hotel")
.id(hotel.getId().toString())
.source(JSON.toJSONString(hotelDoc),XContentType.JSON));
}
//3.发送请求
client.bulk(request,RequestOptions.DEFAULT);
}
@Test
void testUpdateDocumentById() throws IOException {
//1.准备Request
UpdateRequest request = new UpdateRequest("hotel", "36934");
//2.准备请求参数
request.doc(
"price","952",
"starName","五钻"
);
//2.发送请求,得到响应
client.update(request, RequestOptions.DEFAULT);
//3.解析响应结果
}
@Test
void testDeleteDocumentById() throws IOException {
List<Hotel> list = hotelService.list();
//循环删除
for ( Hotel hotel : list ) {
//1.准备Request
DeleteRequest request = new DeleteRequest("hotel", hotel.getId().toString());
//2.发送请求,得到响应
client.delete(request, RequestOptions.DEFAULT);
}
//1.准备Request
DeleteRequest request = new DeleteRequest("hotel", "36934");
//2.发送请求,得到响应
client.delete(request, RequestOptions.DEFAULT);
}
@BeforeEach
void setUp(){
this.client = new RestHighLevelClient(
RestClient.builder(HttpHost.create("http://虚机机地址:es端口")
));
}
@AfterEach
void 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;
@Test
void testMatchAll() throws IOException {
//1 准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
request.source()
.query(QueryBuilders.matchAllQuery());
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4解析响应
handleRequest(response);
}
/**
* 全文检索查询
* @throws IOException
*/
@Test
void testMatch() throws IOException {
//1 准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
request.source()
.query(QueryBuilders.matchQuery("all","如家"));
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
handleRequest(response);
}
/**
* 精确查询、复合查询
* @throws IOException
*/
@Test
void testBool() throws IOException {
//1 准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
//2.1准备BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//2.2添加term
boolQuery.must(QueryBuilders.termQuery("city","上海"));
//2.3添加range
boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
request.source()
.query(boolQuery);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
handleRequest(response);
}
/**
* 排序和分页
* @throws IOException
*/
@Test
void testPageAndSort() throws IOException {
//页码、每页大小
int page = 2,size = 5;
//1 准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
//2.1query
request.source()
.query(QueryBuilders.matchAllQuery());
//2.2排序sort
request.source().sort("price", SortOrder.ASC);
//2.3分页from、size
request.source().from((page-1) * size).size(5);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
handleRequest(response);
}
/**
* 高亮
* @throws IOException
*/
@Test
void testHighlight() throws IOException {
//1 准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
//2.1query
request.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 ) {
//获取文档source
String 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 ) {
//获取文档source
String 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);
}
/**
* 高亮结果解析
*/
@BeforeEach
void setUp(){
this.client = new RestHighLevelClient(
RestClient.builder(HttpHost.create("http://虚拟机地址:es端口号")
));
}
@AfterEach
void tearDown()throws IOException{
this.client.close();
}
}