日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021-04-10 仿牛客网第六章

發布時間:2023/12/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021-04-10 仿牛客网第六章 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Elasticsearch入門

仿牛客網
內容部分引用至 https://blog.csdn.net/weixin_44406146

目錄

  • 一、Elasticsearch入門
    • Elasticsearch配置
    • 安裝中文分詞插件
    • 安裝Postman模擬網頁訪問
    • 使用命令行操作Elasticsearch
    • 使用Postman/RESTer訪問ES
  • 二、Spring整合Elasticsearch
    • 導包
    • 配置
    • 寫數據層
    • 測試一波
  • 三、開發社區搜索功能
    • ElasticsearchService
    • 處理DiscussPostController.addDiscussPost
    • 處理CommentController.addComment
    • EventConsumer寫一個消費發帖事件的方法
    • 新寫一個SearchController
    • 處理頁面index處理搜索框
    • 處理頁面search

  • Elasticsearch簡介

    • 一個分布式的、Restful風格的搜索引擎。
    • 支持對各種類型的數據的檢索。
    • 搜索速度快,可以提供實時的搜索服務。
    • 便于水平擴展,每秒可以處理PB級海量數據。
  • Elasticsearch術語

    • 索引、類型、文檔、字段。
    • 集群、節點、分片、副本。

術語的解釋

  • 索引:相當于數據庫中的database 改版后作為table
  • 類型:相當于數據庫中的table 不再使用
  • 文檔:相當于數據庫中的一行數據,數據結構為JSON
  • 字段:相當于數據庫中的一列

Elasticsearch6.0以后開始逐步廢除類型的概念,索引的含義中也包括了類型。

  • 集群:分布式部署,提高性能
  • 節點:集群中的每一臺服務器
  • 分片:對一個索引的進一步劃分存儲,提高并發處理能力
  • 副本:對分片的備份,提高可用性

    Elasticsearch相關鏈接:官網

Elasticsearch選擇下載6.4.3版本和SpringBoot兼容

Elasticsearch配置

文件位置config/elasticsearch.yml

配置環境變量

安裝中文分詞插件

github上找

解壓到指定目錄下

ik插件配置文件說明

IKAnalyzer.cfg 可以自己配置新詞

安裝Postman模擬網頁訪問

Postman相關鏈接:官網

使用命令行操作Elasticsearch

1.啟動ES—./bin/elasticsearch.bat

2.常用命令介紹

  • 查看節點健康狀態
curl -X GET "localhost:9200/_cat/health?v"

這個命令需要下載curl相關包:參考鏈接

  • 查看節點具體信息
curl -X GET "localhost:9200/_cat/nodes?v"

  • 查看索引相關信息
curl -X GET "localhost:9200/_cat/indices?v"

新裝的沒有索引:

  • 創建索引
curl -X PUT "localhost:9200/test" //test就是索引名字

查看狀態顯示yellow是因為沒有分片(備份)。

  • 刪除索引
curl -X DELETE "localhost:9200/test" //test就是索引名字

使用Postman/RESTer訪問ES

RESTer是火狐插件也很好用。

  • 查索引
  • 建索引
  • 刪除索引
  • 提交數據
//test:索引 _doc:固定格式 1:id號 然后在請求body中寫數據 PUT localhost:9200/test/_doc/1

  • 查數據
GET localhost:9200/test/_doc/1

  • 改數據

和添加數據一樣,底層會先刪除再添加

  • 刪除數據
DELETE localhost:9200/test/_doc/1

  • 搜索功能的演示

    • 先插入一些數據

  • 開始搜索演示

搜索時會先分詞然后搜索,并不一定完全匹配

二、Spring整合Elasticsearch

  • 引入依賴

    • spring-boot-starter-data-elasticsearch
  • 配置Elasticsearch

    • cluster-name、cluster-nodes
  • Spring Data Elasticsearch

    • ElasticsearchTemplate
    • ElasticsearchRepository

導包

<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId> </dependency>

配置

1.application.properties

spring:data:elasticsearch:cluster-name: nowcodercluster-nodes: 127.0.0.1:9300

2.解決Netty沖突問題

問題原因:Redis底層使用了Netty,Elasticsearch也用了Netty,當被注冊兩次就會報錯

解決思路:Elasticsearch中注冊Netty前會判斷有無一個參數,如果有就不注冊

這么解決:

3.給discussPost加注解

//indexName:索引名,type:固定_doc,shards:分片,replicas:備份 @Document(indexName = "discusspost",type = "_doc",shards =6 ,replicas = 2) public class DiscussPost {@Idprivate int id;@Field(type = FieldType.Integer)private int userId;//analyzer:互聯網校招--->建立最大的索引(就是各種拆分)//searchAnalyzer 拆分盡可能少的滿足意圖的分詞器@Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")private String title;@Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")private String content;@Field(type = FieldType.Integer)//0-普通; 1-置頂;private int type;@Field(type = FieldType.Integer)//0-正常; 1-精華; 2-拉黑;private int status;@Field(type = FieldType.Date)private Date createTime;@Field(type = FieldType.Integer)private int commentCount;@Field(type = FieldType.Double)private double score;

寫數據層

在dao下建立子包elasticsearch,并創建DiscussPostRepository接口

測試一波

Elasticsearch中配置再加一個這個:

elasticsearch包不要放在dao包下邊,會導致bean注入失敗。

@SpringBootTest @ContextConfiguration(classes = CommunityApplication.class) public class ElasticsearchTest {@Autowiredprivate DiscussPostMapper discussMapper;@Autowiredprivate DiscussPostRepository discussRepository;//有些功能上邊的解決不了,所以引入下邊的@Autowiredprivate ElasticsearchTemplate elasticTemplate;@Testpublic void testInsert() {discussRepository.save(discussMapper.selectDiscussPostById(271));discussRepository.save(discussMapper.selectDiscussPostById(272));discussRepository.save(discussMapper.selectDiscussPostById(273));}@Testpublic void testInsertList() {discussRepository.saveAll(discussMapper.selectDiscussPosts(101, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(102, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(103, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(111, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(112, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(131, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(132, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(133, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(134, 0, 100));}//localhost:9200/discusspost/_doc/231@Testpublic void testUpdate() {DiscussPost post = discussMapper.selectDiscussPostById(231);post.setContent("我是新人,使勁灌水.");discussRepository.save(post);}@Testpublic void testDelete() {discussRepository.deleteById(231);//discussRepository.deleteAll();}@Testpublic void testSearchByRepository() {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)) //分頁.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")).build();// 底層調用:elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)// 底層獲取得到了高亮顯示的值, 但是沒有返回.所以為了得到高亮顯示直接用elasticTemplate.queryForPage見下面Page<DiscussPost> page = discussRepository.search(searchQuery);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);}}@Testpublic 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)).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() {@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, 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(); //long類型的字符串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(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());}@Overridepublic <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {return null;}});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);}} }

三、開發社區搜索功能

  • 搜索服務

    • 將帖子保存至Elasticsearch服務器。
    • 從Elasticsearch服務器刪除帖子。
    • 從Elasticsearch服務器搜索帖子。
  • 發布事件

    • 發布帖子時,將帖子異步的提交到Elasticsearch服務器。
    • 增加評論時,將帖子異步的提交到Elasticsearch服務器。
    • 在消費組件中增加一個方法,消費帖子發布事件。
  • 顯示結果

    • 在控制器中處理搜索請求,在HTML上顯示搜索結果。

一個小問題的解決

ElasticsearchService

@Service public class ElasticsearchService {@Autowiredprivate DiscussPostRepository discussPostRepository;@Autowiredprivate ElasticsearchTemplate elasticTemplate;//高亮顯示//添加、修改public void saveDiscussPost(DiscussPost discussPost){discussPostRepository.save(discussPost);}//刪除public void deleteDiscussPost(int id){discussPostRepository.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() {@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, 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(); //long類型的字符串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(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());}@Overridepublic <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {return null;}}); } }

處理DiscussPostController.addDiscussPost

處理CommentController.addComment

EventConsumer寫一個消費發帖事件的方法

@KafkaListener(topics = {TOPIC_PUBLISH})public void handlePublishMessage(ConsumerRecord record){if(record==null||record.value()==null){logger.error("消息的內容為空");return;}Event event = JSONObject.parseObject(record.value().toString(),Event.class);if(event==null){logger.error("消息格式錯誤");return;}//查詢出這個帖子DiscussPost post = discussPostService.findDiscussPostById(event.getEntityId());//往es中存數據elasticsearchService.saveDiscussPost(post);}

新寫一個SearchController

@Controller public class SearchController implements CommunityContant {@Autowiredprivate ElasticsearchService elasticsearchService;@Autowiredprivate UserService userService;@Autowiredprivate LikeService likeService;@RequestMapping(path="/search",method = RequestMethod.GET)//路徑 search?keyword=xxxpublic String search(String keyword, Page page, Model model){//搜索帖子org.springframework.data.domain.Page<DiscussPost> searchResult = elasticsearchService.searchDiscussPost(keyword, page.getCurrent() - 1, page.getLimit());//聚合數據List<Map<String,Object>> discussPosts = new ArrayList<>();if(searchResult!=null){for(DiscussPost post:searchResult){Map<String,Object> map = new HashMap<>();//帖子map.put("post",post);//作者map.put("user",userService.findUserById(post.getUserId()));//點贊數量map.put("likeCount",likeService.findEntityLikeCount(ENTITY_TYPE_POST,post.getId()));discussPosts.add(map);}}model.addAttribute("discussPosts",discussPosts);model.addAttribute("keyword",keyword);//分頁信息page.setPath("/search?keyword="+keyword);page.setRows(searchResult==null?0:(int)searchResult.getTotalElements());return "/site/search";} }

處理頁面index處理搜索框

處理頁面search

總結

以上是生活随笔為你收集整理的2021-04-10 仿牛客网第六章的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。