博客项目目录: 请戳这里
需求:用户登录后,发表新文章或者编辑文章,ES会创建或更新对应的文章索引,如果用户删除文章,ES也会删除对应的文章索引。
基本思路:
可以考虑使用rabbitmq来实现,首先配置rabbitmq,将队列和交换机绑定起来。然后在程序中建立监听者,当用户发表或编辑文章时(删除文章时类似),就会收到新建或更新文章索引的消息,然后消费者根据消息类型,进行处理对应的消息。
RabbitMq相关依赖用于整合RabbitMq,项目启动时,需要事先安装RabbitMq,并开启RabbitMq服务
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
将交换机和队列绑定起来,并配置一个key,当监听者监听到对应的消息,就会将消息发送给队列,然后消费者来消费对应类型的消息。
@Configuration
public class RabbitMqConfig {
public final static String es_queue = "es_queue";
public final static String es_exchage = "es_exchage";
public final static String es_bind_key = "es_exchage";
@Bean
public Queue exQueue() {
return new Queue(es_queue);
}
@Bean
DirectExchange exchange() {
return new DirectExchange(es_exchage);
}
@Bean
Binding binding(Queue exQueue, DirectExchange exchange) {
return BindingBuilder.bind(exQueue).to(exchange).with(es_bind_key);
}
}
注入模板
在PostController提交帖子的逻辑下,添加如下代码,表示新建文章或更新文章时,就会通过对应的通道,将消息发送给队列
//通知消息给mq,告知更新或添加
amqpTemplate.convertAndSend(RabbitMqConfig.es_exchage, RabbitMqConfig.es_bind_key,
new PostMqIndexMessage(post.getId(), PostMqIndexMessage.CREATE_OR_UPDATE));
在PostController删除帖子的逻辑下,添加如下代码,表示删除文章时,就会通过对应的通道,将消息发送给队列
1.新增消息类型实体
@Data
@AllArgsConstructor
public class PostMqIndexMessage implements Serializable {
// 两种type
public final static String CREATE_OR_UPDATE = "create_update";
public final static String REMOVE = "remove";
private Long postId;
private String type;
}
2.消息处理器
如果是"create_update"类型的消息,就执行createOrUpdateIndex()方法;如果是"remove"类型的消息,就执行removeIndex()方法
@Slf4j
@Component
@RabbitListener(queues = RabbitMqConfig.es_queue)
public class MqMessageHandler {
@Autowired
SearchService searchService;
@RabbitHandler
public void handler(PostMqIndexMessage message) {
log.info("mq 收到一条消息: {}", message.toString());
switch (message.getType()) {
case PostMqIndexMessage.CREATE_OR_UPDATE:
searchService.createOrUpdateIndex(message);
break;
case PostMqIndexMessage.REMOVE:
searchService.removeIndex(message);
break;
default:
log.error("没找到对应的消息类型,请注意!! --》 {}", message.toString());
break;
}
}
}
public interface SearchService {
IPage search(Page page, String keyword);
int initEsData(List<PostVo> records);
void createOrUpdateIndex(PostMqIndexMessage message);
void removeIndex(PostMqIndexMessage message);
}
如果是新建文章或跟新文章,首先获取文章Id,找到对应的PostVo,然后转化为文档形式,储存到ES;如果是删除文章,同样先获取文章Id,然后在ES根据Id删除对应文章索引。
@Override
public void createOrUpdateIndex(PostMqIndexMessage message) {
Long postId = message.getPostId();
PostVo postVo = postService.selectOnePost(new QueryWrapper<Post>().eq("p.id", postId));
PostDocment postDocment = modelMapper.map(postVo, PostDocment.class);
postRepository.save(postDocment);
log.info("es 索引更新成功! ---> {}", postDocment.toString());
}
@Override
public void removeIndex(PostMqIndexMessage message) {
Long postId = message.getPostId();
postRepository.deleteById(postId);
log.info("es 索引删除成功! ---> {}", message.toString());
}
https://github.com/MarkerHub/eblog