在刚才的新增当中,我们是一次新增一条数据。那么如果你将来的数据库里有数千上万的数据,你一次新增一个,那得多麻烦。所以我们还要学习一下批量导入功能。
也就是说批量的把数据库的数据写入索引库。那这里的需求是,首先利用mybatisplus去批量查询酒店数据,然后将查询到的酒店数据,也就是hotel把它转换成我们的hotelDoc文档类型。最后再利用我们的这个Bulk批处理方式实现批量新增:
@Test
void testCreateHotelIndex() throws IOException{
//创建索引库 CreateIndexReqeust
//1、创建Request对象:
CreateIndexRequest request = new CreateIndexRequest("hotel");
//2、请求参数:
request.source(MAPPING_TEMPLATE, XContentType.JSON);
//3、发送请求
client.indices().create(request,RequestOptions.DEFAULT);
}
//1、创建DeleteIndexRequset
DeleteIndexReqeust reqeust = new DeleteIndexReqeust("hotel");
client.indices().delete(reqeust. ReqeustOptions.DEFAULT);
//判读索引库是否存在:
GetIndexReqeust request = new GetIndexRequest("hotel");
boolean exists = client.indices().exists(reqeust, RequestOptions.DEFAULT);
@Test
void testBulkRequest() throws IOException{
List<Hotel> hotels = hoteService.list();
BulkRequest request = new BulkRequest();
for(Hotel hotel : hotels){
HotelDoc hotelDoc = new HotelDoc(hotel);
request.add(new IndexRequest("hotel"))
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
}
// 发送请求
client.bulk(request,RequestOptions.DEFAULT);
}
用Stream+Map转换更优雅:
@Test
void testBulkRequest() throws IOException {
List<Hotel> hotels = hoteService.list();
BulkRequest request = new BulkRequest();
hotels.stream()
.map(hotel -> new HotelDoc(hotel))
.forEach(hotelDoc -> {
try {
request.add(new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON));
} catch (IOException e) {
// Handle exception
e.printStackTrace();
}
});
client.bulk(request, RequestOptions.DEFAULT);
}
其实是把多个 IndexRequest的请求合并到BulkRequest 对象里,然后一次性完成提交,这种就叫批处理,确实没有什么新东西, 就是把以前的那种新增的代码给它合到一起去提交了。
接下来我们就来学习第一种全文检索查询。全文检索查询它会对用户输入的内容做分词以后进行匹配。比较常见的用于这个搜索框的这种搜索
match和multi_match的区别是什么?一个是根据单字段查询,一个是根据多字段。而multi_match参与查询的字段越多,性能越差,建议利用copy to把多个要查的字段拷贝到一个字段当中
什么是死锁:
在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。
死锁产生的四个必要条件:(有一个条件不成立,则不会产生死锁)互斥条件:一个资源一次只能被一个进程使用
·请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放·不剥夺条件:进程获得的资源,在未完全使用完之前,不能强行剥夺·循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系如何处理死锁问题
常用的处理死锁的方法有:死锁预防、死锁避免、死锁检测、死锁解除、鸵鸟策略。
什么是长连接和短连接?
长连接和短连接是两种常见的网络连接方式,主要用于HTTP、WebSocket等协议。
长连接(Long-Connection):在长连接模式下,客户端和服务器之间的连接是持久的,并且在一段时间内保持打开状态。这意味着在一段时间内,客户端和服务器可以共享同一个连接,从而减少了建立新连接的开销。长连接适用于需要频繁通信的场景,例如实时聊天应用、实时游戏等。在长连接中,客户端和服务器通常会保持连接直到一方主动关闭。
短连接(Short-Connection):在短连接模式下,客户端和服务器之间的连接是短暂的,每次通信都会建立新的连接。这意味着在每次通信结束后,服务器和客户端会关闭连接。短连接适用于非实时通信场景,例如文件传输、请求-响应模式的应用程序等。在短连接中,客户端通常会定期发送请求以保持活跃状态,并在收到响应后关闭连接。
总的来说,长连接和短连接的主要区别在于连接的生命周期和适用场景。长连接适用于需要频繁通信的实时应用场景,而短连接适用于非实时的通信场景。在实际应用中,可以根据具体需求选择合适的连接方式。
Rabbitmq中的长连接的作用
在 RabbitMQ 中,消费者是指从队列中获取消息并进行处理的应用程序或系统。消费者通常会建立一个长期的连接到 RabbitMQ 服务器,以便实时地从队列中获取消息。这种长期连接的特性称为长连接。
长连接的工作方式如下:
-
连接建立:消费者应用程序通过 RabbitMQ 提供的客户端库建立到 RabbitMQ 服务器的连接。这个连接是持久的,意味着一旦建立,它会保持打开状态,直到显式关闭或发生异常。
-
通道创建:一旦连接建立,消费者会在连接上创建一个或多个通道(Channel)。通道是在连接上进行多路复用的机制,它允许在单个连接上进行多个独立的通信会话。消费者通过通道与 RabbitMQ 进行消息传输和交互。
-
订阅队列:消费者通过通道订阅一个或多个队列,以便从中接收消息。订阅队列后,消费者会开始接收队列中的消息,并进行处理。
-
消息获取和处理:一旦订阅了队列,消费者就会持续地从队列中获取消息。获取到消息后,消费者会对消息进行处理,可能是执行某些业务逻辑、存储到数据库或转发到其他系统等操作。
-
消息确认:处理完消息后,消费者可能会向 RabbitMQ 发送确认消息(acknowledgement),告知 RabbitMQ 该消息已经被成功处理。RabbitMQ 根据消费者的确认消息来确定是否将消息标记为已处理,并从队列中删除。
通过建立长连接和使用通道,消费者可以实时地从队列中获取消息,并保持与 RabbitMQ 的高效通信。这种长连接的机制使得消费者能够快速响应消息,并且减少了频繁建立和断开连接的开销,提高了系统的性能和效率。