Spring boot 论坛项目实战_06
目前性能最好的搜索引擎
1. Elasticsearch入门
-
Elasticsearch简介
-
一个分布式的、Restful风格的搜索引擎
-
分布式:多台服务器、集群式部署
-
Restful:设计风格,规定前后端交互方式
-
-
支持对各种类型的数据的检索
-
搜索速度快,可以提供 实时 的搜索服务
-
便于水平扩展,每秒可以处理PB级海量数据
-
-
Elasticsearch术语【mysql中相对对象】
-
索引【库】、类型【表】、文档{json结构}【一行数据】、字段{json中一个属性}【一列】
-
6.0 版本后,类型逐渐被废弃,索引对应【表】,类型被固定成一个单词
-
7.0 版本后,类型彻底被废弃
-
-
集群、节点【某一台服务器】、分片【对这个索引的进一步划分、提高并发能力】、副本【对分片的备份】
-
-
参考网站:
Elasticsearch安装
-
务必考虑自身当前的 Spring 与 Elasticsearch 兼容问题, 选择合适的版本
-
本次环境使用的 Elasticsearch 版本为 6.4.3
配置 ES 相关属性:
-
Config/elasticsearch.yml 文件
-
配置集群名字:自定义,这里自定为 nowcoder
-
配置文件存储位置、日志存放位置:
配置环境变量【Windows 平台】
-
往Path 中添加解压后ES 的 bin目录即可
安装中文分词软件
-
Github 搜索: elasticsearch ik
-
选择和你安装的 ES 对应的 ik 版本
-
下载第一个 zip 即可
-
文件必须解压到 ES\plugins\ik 目录下
-
将分词 ik 直接解压到 ik 文件目录下:
-
更新网络新词 配置:
安装 Postman【可选】
-
一个web 模拟工具
常用命令访问 ES【查询健康状态、查询节点、查询索引、新增索引、删除索引】
记得先去 ES 的 bin 下 启动 elasticsearch.bat 服务
2. Spring 整合 Elasticsearch
-
引入依赖
-
spring-boot-starter-data-elasticsearch
-
-
配置Elasticsearch
-
cluster-name、cluster-nodes
-
-
Spring Data Elasticsearch
-
ElasticsearchTemplate
-
ElasticsearchRepository
-
运行时报错::
NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{127.0.0.1}{127.0.0.1:9300}]]
-
解决方法:
-
修改 elasticsearch.yml
-
修改服务器地址, 记得把 http 的端口放出来, java 运行的是 FTP 的 9300 端口
-
-
Java 实现 ES 查询方法:
-
// 搜索功能
// withQuery: 【搜索条件】
// withSort: 【排序条件】
// withPageable:【分页条件】
// withHighlightFields :【指定高亮显示】
// build() 执行方法, 生成 SearchQuery 对象实现类
-
-
用Template 处理高亮显示
-
@Test public void testSearchByTemplate() { SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "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(0, 10))//of(第几页,显示条数) .withHighlightFields( new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"), new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>") ).build(); Page<DiscussPost> page = elasticTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() { @Override public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) { // 本次查询获取的多条数据 SearchHits hits = response.getHits(); if (hits.getTotalHits() <= 0) { return null; } 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.setTitle(contentField.getFragments()[0].toString()); } list.add(post); } return new AggregatedPageImpl(list,pageable, hits.getTotalHits(),response.getAggregations(),response.getScrollId(),hits.getMaxScore()); } }); System.out.println(page.getTotalElements()); System.out.println(page.getTotalPages()); System.out.println(page.getNumber()); System.out.println(page.getSize()); for (DiscussPost post : page) { System.out.println(post); } }
-
可以看到,现在运行结果中,关键词是带了标签的
-
3. 开发社区搜索功能
-
搜索服务
-
将帖子保存至 Elasticsearch 服务器
-
从 Elasticsearch 服务器删除帖子
-
从 Elasticsearch 服务器搜索帖子
-
-
发布事件
-
-
增加评论时,将帖子异步的提交到 Elasticsearch 服务器
-
在消费组件中增加一个方法,消费帖子发布事件
-
-
显示结果
-