赞
踩
es简介
基本术语
在es6.x以后,类型 将被废弃 索引直接与关系型数据库的表对应
项目使用的是springboot2.1.5,所以es需要使用6.4.3
安装es中文分词插件
SpringBoot整合Elasticsearch
引入依赖
spring-boot-starter-data-elasticsearch
配置Elasticsearch
cluster-name、cluster-nodes
配置完成之后需要注意一个小问题,如果项目中还有redis的话,在项目启动时会有冲突,因为redis与es底层都依赖于netty,解决方法:
@SpringBootApplication
public class CommunityApplication {
// @PostConstruct管理bean的初始化方法,在构造器调用完以后被执行
@PostConstruct
public void init(){
//解决netty启动冲突问题
//see Netty4Util
System.setProperty("es.set.netty.runtime.available.processors","false");
}
public static void main(String[] args) {
SpringApplication.run(CommunityApplication.class, args);
}
}
Spring Dataa Elasticsearch
ElasticsearchTemplate
ElasticsearchRepository
项目中使用ElasticsearchRepository,首先需要将实体类映射至es,在实体类中加上注解,实例:
ok,简单将我们数据库字段映射之后,进行简单测试
使用此方式查询高亮显示内容无法插入到原数据中,所以选择Template来执行查询(因为高亮内容是单独的,所以需要手动替换)
为了完成高亮显示功能,需要使用queryForPage方法,在SearchResultMapper中整合数据,具体看mapResults的操作
将数据依次封装,返回结果。
es应用
在项目中进行文章的检索功能
搜索服务
将帖子保存至Es服务器中
从Es服务器删除帖子
从Es服务器中搜索帖子
发布事件
发布帖子时,将帖子异步的提交到Es服务器
增加评论时,将帖子异步提交到Es服务器
在消费组件中增加一个方法,消费帖子发布事件。
显示结果
在控制器处理搜索请求,在HTML上显示搜索结果
编写Service,使用Repository加Template查询
/** * @author :LY * @date :Created in 2021/3/9 11:31 * @modified By: */ @Service public class ElasticsearchService { @Autowired private DiscussPostRepository discussRepository; @Autowired private ElasticsearchTemplate elasticTemplate; public void saveDiscussPost(DiscussPost discussPost){ discussRepository.save(discussPost); } public void deleteDiscussPost(int id){ discussRepository.deleteById(id); } public Page<DiscussPost> searchDiscussPost(String keyword, int current,int limit){ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.multiMatchQuery(keyword,"title","content")) .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC)) .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC)) .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC)) .withPageable(PageRequest.of(current,limit)) .withHighlightFields( new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>") ).build(); return elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() { @Override public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) { //首先通过searchResponse得到这次搜索得到的数据 SearchHits hits = searchResponse.getHits(); List<DiscussPost> list = new ArrayList<>(); for (SearchHit hit : hits){ DiscussPost post = new DiscussPost(); String id = hit.getSourceAsMap().get("id").toString(); post.setId(Integer.valueOf(id)); String userId = hit.getSourceAsMap().get("userId").toString(); post.setUserId(Integer.valueOf(userId)); String title = hit.getSourceAsMap().get("title").toString(); post.setTitle(title); String content = hit.getSourceAsMap().get("content").toString(); post.setContent(content); String status = hit.getSourceAsMap().get("status").toString(); post.setStatus(Integer.valueOf(status)); String createTime = hit.getSourceAsMap().get("createTime").toString(); post.setCreateTime(new Date(Long.valueOf(createTime))); String commentCount = hit.getSourceAsMap().get("commentCount").toString(); post.setCommentCount(Integer.valueOf(commentCount)); //处理高亮显示的结果 HighlightField titleField = hit.getHighlightFields().get("title"); if (titleField != null){ post.setTitle(titleField.getFragments()[0].toString()); } HighlightField contentField = hit.getHighlightFields().get("content"); if (contentField != null){ post.setContent(contentField.getFragments()[0].toString()); } list.add(post); } return new AggregatedPageImpl(list,pageable, hits.getTotalHits(),searchResponse.getAggregations(), searchResponse.getScrollId(),hits.getMaxScore()); } }); } }
controller编写
/** * @author :LY * @date :Created in 2021/3/9 15:21 * @modified By: */ @Controller public class SearchController { @Autowired private ElasticsearchService elasticsearchService; @Autowired private UserSerice userSerice; @Autowired private LikeService likeService; @GetMapping("/search") public String search(String keyword, Page page, Model model){ //搜索 org.springframework.data.domain.Page<DiscussPost> searchDiscussPost = elasticsearchService.searchDiscussPost(keyword, page.getCurrent() - 1, page.getLimit()); //聚合数据 List<Map<String,Object>> discussPosts = new ArrayList<>(); if(searchDiscussPost != null){ searchDiscussPost.forEach(discussPost -> { Map<String,Object> map = new HashMap<>(); //帖子 map.put("post",discussPost); //作者 map.put("user",userSerice.findUserById(discussPost.getUserId())); //点赞数量 map.put("likeCount",likeService.findEntityLikeCount(CommunityConstant.ENTITY_TYPE_POST.getValue(), discussPost.getId())); discussPosts.add(map); }); } model.addAttribute("discussPosts",discussPosts); model.addAttribute("keyword",keyword); //分页信息 page.setPath("/search?keyword="+keyword); page.setRows(searchDiscussPost == null?0:(int) searchDiscussPost.getTotalElements()); return "/site/search"; } }
高亮效果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。