日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

今天要聊的就是「博客管理」中全文搜索的實現,基于 SpringBoot+Vue+ES 實現,先給大家看一下效果:


 

全文搜索+關鍵字高亮,是不是和百度的效果差不多,話不多說,直接聊如何實現。

 

該網站前端是仿一個開源項目,本人主要是做后端,所以本教程涉及前端的部分會直接給代碼,不做深入講解
數據準備

 

首先我們的數據是存放在 MySQL 的,建表語句如下,再利用 MyBatis-Plus 實現普通查詢,比較簡單,也不是本文重點,不做贅述。

create table code_note ( id bigint not null auto_increment, title varchar(128) not null default '' comment '標題', md_content text comment 'md文本', html_content text comment 'html文本', summary varchar(256) comment '摘要', category varchar(10) comment '分類', type tinyint not null default 0 comment '類型:0-文字;1-視頻', create_time datetime not null comment '創建時間', publish_time datetime not null comment '發布時間', status tinyint DEFAULT 0 COMMENT '0-草稿箱;1-已發表;2-已刪除', primary key (id) ); INSERT INTO yitiao_admin.code_note (id, title, author, md_content, html_content, summary, category, type, create_time, publish_time, status) VALUES (14, '一條', 'yitiao', 'canal', '

canal

', null, '默認', null, '2023-01-30 10:28:17', '2023-01-30 10:28:17', 1); 復制代碼 前端頁面

前端是基于 element-ui 來實現的,從文檔找了半天,決定用 table 來實現,如果有更好的實現方式可以評論區留言。

其實就是只有的一列的無邊框的表格,表格內又嵌入文本和按鈕,再就是一些樣式的調整,關鍵代碼如下:

border >

 

margin-top: 5px;font-size: medium" v-html="scope.row.esContent">

{{ scope.row.author }} {{ scope.row.createTime }}

 

復制代碼

「查詢」和「全文搜索」按鈕的切換使用的 v-if="searchShow",向后端發請求的部分如下:

fullSearch() { this.searchShow = true; this.pageShow = false; if (this.search === '' || this.Search === null) { this.search = 'spring' } request.get("/es/note/getByContent/", { params: { // pageNum: this.currentPage, // pageSize: this.pageSize, content: this.search } }).then(res => { console.log(res) this.searchTableData = res.data }) } 復制代碼 Docker安裝ES

終于要到正題啦,因為ES非常的耗內存,我的服務器剩余內存只有不到2G,所以選擇用Docker部署單機版的ES。

sudo docker pull ElasticSearch:7.12.0 ## 創建掛載目錄 config、data、plugins,開啟全部權限 chmod -R 777 /data/opt/es ## 創建配置文件 cd config vim elasticsearch.yml http.host: 0.0.0.0 ## 啟動容器 sudo docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms84m -Xmx512m" -v /data/opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /data/opt/es/data:/usr/share/elasticsearch/data -v /data/opt/es/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.12.0 # 查看日志 docker logs elasticsearch 復制代碼

測試正常啟動頁面:http://101.43.138.173:9200/

插件使用


 

集群黃色解決


 

我們的elasticsearch是單節點的,只有一個主服務沒有從服務,也就是說所以最簡單的辦法就是在創建索引的時候將備份數改為0。

如果我們已經創建了索引,那么我們可以直接更改索引的備份數方法舉例如下:

## 請求方式為put ## url地址解釋:IP地址:端口/索引名稱/_settings(_settings 是接口的固定用法) curl -X PUT -H "Content-Type: Application/json" -d '{"number_of_replicas":0}' http://101.43.138.173:9200/Code_note/_settings --user name:password ## 返回 {"acknowledged":true} 復制代碼

刷新插件,集群變成綠色。

設置用戶名密碼

# vim elasticsearch.yml http.cors.enabled: true http.cors.allow-origin: "*" http.cors.allow-headers: Authorization xpack.security.enabled: true xpack.security.transport.ssl.enabled: true 復制代碼 docker exec -it fa41ca453d06 /bin/bash ./bin/elasticsearch-setup-passwords interactive ## 輸入密碼 復制代碼


 

設置成功后,用戶名為elastic,密碼為設置的值,同時es里多了一個索引:.security-7


 

安裝分詞器

下載,版本一定要和es的對應,安裝時注意,并不是一解壓就好了。

首先查看插件的名字,解壓后打開plugin-descriptor.properties文件,查看插件的名字,然后在掛載的plugins文件夾下新建文件夾,以插件的名字命名。

再將解壓出來文件全部移動到插件名文件夾下才可以。


 

重啟ES,查看日志

docker restart fa41ca453d06 docker logs fa41ca453d06 復制代碼

至此,ES服務端部署完成,接下來就是基于SpringBoot操作ES。

Java客戶端

spring-boot-starter-data-elasticsearch是比較好用的一個elasticsearch客戶端,它內部會引入spring-data-elasticsearch。

版本對應關系

 

如果使用spring-boot-starter-data-elasticsearch,需要調整spring-boot的版本才起作用。

 


 

有下邊這幾種方法操作ElasticSearch:

 

  • ElasticsearchRepository(傳統的方法,可以使用)
  • ElasticsearchRestTemplate(推薦使用。基于RestHighLevelClient)
  • ElasticsearchTemplate(ES7中廢棄,不建議使用。基于TransportClient)
  • RestHighLevelClient(推薦度低于ElasticsearchRestTemplate,因為API不夠高級)
  • TransportClient(ES7中廢棄,不建議使用)

 

案例代碼

配置

org.springframework.boot spring-boot-starter-data-elasticsearch 2.7.7 復制代碼 spring: elasticsearch: rest: uris: 101.43.138.173:9200 # 多個用逗號隔開 # username: ---用戶名 # password: ---密碼 connection-timeout: 1000 # 連接超時時間 read-timeout: 1000 # 讀取超時時間 復制代碼

索引類

// 省略部分字段 @Data @Document(indexName = "code_note") @Setting(replicas = 0) // 副本為0,單機模式 @NoArgsConstructor @AllArgsConstructor @Builder public class EsCodeNote { @Id private Long id; /** * md文本 */ @Field(type = FieldType.Text, analyzer = "ik_max_word") private String mdContent; /** * 分類 */ @Field(type = FieldType.Keyword) private String category; /** * 創建時間 */ @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis") private Date createTime; } 復制代碼

mapper類

@Repository public interface CodeNoteRepository extends ElasticsearchRepository { } 復制代碼

service層

@Service @Slf4j @RequiredArgsConstructor public class CodeNoteService { private final ElasticsearchRestTemplate esRestTemplate; private final CodeNoteRepository codeNoteRepository; private final CodeNoteMapper noteMapper; public Object saveNoteToEs(EsCodeNote codeNote){ return codeNoteRepository.save(codeNote); } public void saveNotesToEs(List codeNotes){ codeNoteRepository.saveAll(codeNotes); } public List getFromEsByContent(String content) { //高亮 String preTag = ""; String postTag = ""; boolQueryBuilder boolQueryBuilder = new BoolQueryBuilder().should(new MatchQueryBuilder("mdContent", content)); Query query = new NativeSearchQueryBuilder() .withQuery(boolQueryBuilder) .withHighlightFields(new HighlightBuilder.Field("mdContent").preTags(preTag).postTags(postTag)).build(); // Query query1 = new NativeSearchQueryBuilder() // .withQuery(QueryBuilders.multiMatchQuery(content,"content","content.inner")).build(); // .withQuery(QueryBuilders.queryStringQuery(content)).build(); SearchHits search = esRestTemplate.search(query, EsCodeNote.class); return search.stream().map(SearchHit::getContent).collect(Collectors.toList()); } public void init() { List codeNotes = noteMapper.selectList(Wrappers.lambdaQuery(CodeNote.class)); List esCodeNotes = BeanUtil.copyToList(codeNotes, EsCodeNote.class); this.saveNotesToEs(esCodeNotes); } } 復制代碼

controller

@RestController @RequestMapping("/es") @Slf4j @RequiredArgsConstructor public class EsRestController { private final CodeNoteService noteService; @PostMapping("/init") public Result createIndex() { noteService.init(); return Result.success("init all notes success"); } @GetMapping("/note/getByContent") public Result> getByContent(@RequestParam("content")String content) { return Result.success(noteService.getFromEsByContent(content)); } } 復制代碼

測試

先初始化全部數據

根據mdContent分詞查詢

至此后端的高亮查詢已經實現,如果與前端結合,還需要對查詢結果做進一步封裝和處理。

前后端聯調

后端構建返回VO

public class EsCodeNoteRes { private Long id; /** * 題目 */ private String esTitle; private String author; /** * md文本 */ private String esContent; /** * html文本 */ private String htmlContent; // 省略部分 /** * 發布時間 */ @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date publishTime; } 復制代碼

對返回的結果封裝

SearchHits searchHits = esRestTemplate.search(query, EsCodeNote.class); return searchHits.stream().map(search -> { EsCodeNote esCodeNote = search.getContent(); search.getHighlightFields().forEach((k, v) -> { log.info("highlight key is [{}],content is [{}]", k, v.get(0)); // 分別處理標題和正文 if (k.equals("title")) { esCodeNote.setTitle(v.get(0)); } if (k.equals("mdContent")) { esCodeNote.setMdContent(v.get(0)); } }); // 如果正文里沒有關鍵字,取前100字符 if (!esCodeNote.getMdContent().contains(postTag)){ esCodeNote.setMdContent(esCodeNote.getMdContent().substring(0,100)); } return EsCodeNoteRes.builder() .id(esCodeNote.getId()) .esTitle(esCodeNote.getTitle()) .author(esCodeNote.getAuthor()) .esContent(esCodeNote.getMdContent()) .htmlContent(esCodeNote.getHtmlContent()) .summary(esCodeNote.getSummary()) .category(esCodeNote.getCategory()) .createTime(esCodeNote.getCreateTime()) .publishTime(esCodeNote.getPublishTime()) .build(); }).collect(Collectors.toList()); 復制代碼

結果展示


 

道阻且長,行則將至。2023,揚帆起航


原文鏈接:https://juejin.cn/post/7194734486327099429

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定