SpringBoot+ ElasticSearch實現全文搜索功能

2021-03-02 Java項目開發

優質文章,及時送達

前端:html

後端:springboot+ElasticSearch
jdk:1.8及以上

資料庫:沒有用到mysql (數據直接存到es表)


掃碼關注回復【搜尋引擎】獲取完整源碼

如果你在運行這個代碼的過程中有遇到問題,請加小編微信xxf960513,我拉你進對應微信學習群!!幫助你快速掌握這個功能代碼!

<!doctype html><html xmlns:th="http://www.thymeleaf.org"><head th:replace="front::head('es搜索')"></head><style type="text/css"></style></head><body><div th:replace="front::scripts"></div><div id="app">    <div class="row">        <form action="/sp/user/searchList" method="GET">            <div class="search-background">                <div style="text-align: center;">                    <p class="font_title_large" style="color: #fff;">搜索一下</p>                    <p class="font_base" style="color: #fff;">智能檢索,輕鬆查詢</p>                </div>                <div class="search-box">                    <el-input placeholder="請輸入內容" v-model="input" class="input-with-select">                        <el-select v-model="select" slot="prepend" placeholder="請選擇">                            <el-option label="全部" value="0" selected></el-option>                        </el-select>                        <el-button slot="append" icon="el-icon-search" v-on:click="onSubmit"></el-button>                    </el-input>                </div>            </div>        </form>    </div></div><div class="container-fluid">    <div class="row">        <div class="col-md-1"></div>        <div class="col-md-7">            <div class="searchNum">                <span class="classRemarks" style="font-weight:bold;" th:utext="${message}"></span>                <span class="classRemarks" th:if="${message == null}">為您找到相關結果約<span style="color:#f00;" th:utext="${recordTotal}"></span>個</span>
</div> <div th:each="list:${standardBaseList}"> <div class="contentBox row" style="margin-bottom: 20px;">
<div class="textDetailBox col-md-8"> <p class="classTitle" style="font-size: 18px;" th:utext="${list.title}"></p> <p class="classDetail" style="font-size: 16px;" th:utext="${list.content}"></p> <div th:if="${list.createTime!= null}" style="margin-top:10px"> 創建時間: <span style="margin-left:10px;" class="classRemarks" th:utext="${list.createTime}"></span> </div> </div>
</div> </div> <div th:replace="front::btn_pager"></div> </div> </div></div>

<script> new Vue({ el: '#app', data: { activeIndex: '3', input: '', select: '1' }, created: function(){ this.input = this.getUrlParam("keywords"); this.select = this.getUrlParam("keyvalues"); if(this.select == null){ this.input = "測試"; this.select = "全部"; } }, methods: { onSubmit:function () { window.location.href = "/sp/user/searchList?keyvalues="+this.select+"&keywords="+this.input; }, getUrlParam(key) { var url = window.location.search; var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)"); var result = url.substr(1).match(reg); return result ? decodeURIComponent(result[2]) : null; } }
})</script></body></html>
 

  server:  port: 9080spring:  data:    elasticsearch:      cluster-nodes: xx.xx.xx.xx:9300    redis:      repositories:        enabled: false  thymeleaf:    cache: false    prefix: classpath:/templates/    suffix: .html    servlet:      content-type: text/html    mode: HTML5    encoding: UTF-8    resources:      chain:        strategy:          content:            enabled: true            paths: /**wangzz:  elasticsearch:    hostlist: ${eshostlist:xx.xx.xx.xx:8085}    searchIndex: test    searchType: active

package com.iistd.config;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
@Configurationpublic class ElasticsearchConfig {
@Value("${wangzz.elasticsearch.hostlist}") private String hostlist;
@Bean public RestHighLevelClient restHighLevelClient(){ String[] split = hostlist.split(","); HttpHost[] httpHostArray = new HttpHost[split.length]; for(int i=0;i<split.length;i++){ String item = split[i]; httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http"); } return new RestHighLevelClient(restClient()); }
@Bean public RestClient restClient(){ String[] split = hostlist.split(","); HttpHost[] httpHostArray = new HttpHost[split.length]; for(int i=0;i<split.length;i++){ String item = split[i]; httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http"); } return RestClient.builder(httpHostArray).build(); }
}

package com.iistd.entity;import java.io.Serializable;import java.util.Date;import lombok.Data;import org.springframework.data.annotation.Id;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.annotations.Field;
@Data@Document(indexName = "test",type = "active")public class Search implements Serializable{ @Id public String id; @Field(index = true,analyzer = "ik_smart",searchAnalyzer = "ik_smart") public String title; @Field(index = true,analyzer = "ik_smart",searchAnalyzer = "ik_smart") public String content; public String remark; public String createTime;}

package com.iistd.serveiceImpl;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Map;import com.iistd.util.Pager;import org.elasticsearch.action.search.SearchRequest;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.elasticsearch.common.text.Text;import org.elasticsearch.index.query.*;import org.elasticsearch.search.SearchHit;import org.elasticsearch.search.SearchHits;import org.elasticsearch.search.builder.SearchSourceBuilder;import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import com.iistd.entity.Search;
@Servicepublic class SearchService{
@Autowired RestClient restClient;
@Autowired RestHighLevelClient client;
@Value("${wangzz.elasticsearch.searchIndex}") private String searchIndex;
@Value("${wangzz.elasticsearch.searchType}") private String searchType;
public Pager<Search> findByPage(String keywords, String page) { try{ List<Search> list = SearchData(keywords); Pager<Search> pager = new Pager<>(list,1, 10); if(page != null ) { pager = new Pager<>(list,Integer.parseInt(page),10); } return pager; }catch (Exception e){ System.out.println(e); return null; }
}
public List<Search> SearchData(String keywords) throws IOException { SearchRequest searchRequest = new SearchRequest(searchIndex); searchRequest.types(searchType); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "title", "content") .minimumShouldMatch("50%") .field("title", 10);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(multiMatchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<tag>"); highlightBuilder.postTags("</tag>"); highlightBuilder.fields().add(new HighlightBuilder.Field("title")); highlightBuilder.fields().add(new HighlightBuilder.Field("content")); searchSourceBuilder.highlighter(highlightBuilder).size(10000);
searchRequest.source(searchSourceBuilder).scroll(); SearchResponse searchResponse = client.search(searchRequest); SearchHits hits = searchResponse.getHits(); SearchHit[] searchHits = hits.getHits(); List<Search> list = new ArrayList<>(); for(SearchHit hit:searchHits){ Search search = new Search(); String id = hit.getId(); Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String title = (String) sourceAsMap.get("title"); String content = (String) sourceAsMap.get("content");
Map<String, HighlightField> highlightFields = hit.getHighlightFields(); if(highlightFields!=null){ HighlightField titleLight = highlightFields.get("title"); if(titleLight!=null){ Text[] fragments = titleLight.getFragments(); StringBuffer stringBuffer = new StringBuffer(); for(Text text:fragments){ stringBuffer.append(text); } title = stringBuffer.toString(); } HighlightField contentLight = highlightFields.get("content"); if(contentLight!=null){ Text[] fragments = contentLight.getFragments(); StringBuffer stringBuffer = new StringBuffer(); for(Text text:fragments){ stringBuffer.append(text); } content = stringBuffer.toString(); } } search.setTitle(title); search.setContent(content); search.setRemark((String)sourceAsMap.get("remark")); search.setCreateTime((String)sourceAsMap.get("createTime"));
list.add(search); } return list;  }}

package com.iistd.controller.frontController;import com.iistd.entity.Search;import com.iistd.serveiceImpl.SearchService;import com.iistd.util.Pager;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
@RestController@RequestMapping("/sp/user")public class SearchController {
@Autowired private SearchService searchService; @RequestMapping(value = "/searchList",method = RequestMethod.GET) public ModelAndView searchByKeyWords(String keywords, String page) { ModelAndView mv = new ModelAndView(); mv.setViewName("homepage/search/searchList"); if(keywords == null){ keywords = "測試"; }
Pager<Search> pager = searchService.findByPage(keywords,page); if(pager != null){ mv.addObject("standardBaseList", pager.getPageContent()); mv.addObject("pageTotal", pager.getPageTotal()); mv.addObject("page", pager.getCurrentPage()); mv.addObject("recordTotal", pager.getRecordTotal()); mv.addObject("keywords",keywords); }else{ mv.addObject("message","沒有查到相關信息呦~換個詞查吧"); } return mv; }}

import com.iistd.IistdApplication;import com.iistd.dao.SearchDao;import com.iistd.entity.Search;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTest(classes={IistdApplication.class})public class esTest {    @Autowired    SearchDao searchDao;    @Test    public void test(){        Search search = new Search();        search.setTitle("《Java編程思想》");        search.setContent("適合對象:java初級、中級;偏重編程思想,java如果沒有基礎看此書會有點晦澀難懂,枯燥乏味。當你有些編程經驗之後,再來看這本書。多寫代碼,多思考會對你的編程思想有很大提升。");        search.setCreateTime("2020-09-13");        searchDao.save(search);
search.setTitle("《Effective Java》"); search.setContent("適合對象:javajava初級、中級;同樣是翻譯版,雖有些瑕疵,不影響閱讀和體驗。不過作為進階技術書籍,讀懂它和分辨出瑕疵來,也說明你的功力更進一步了。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《資料庫原理》"); search.setContent("適合對象:javajava初級、中級、高級;資料庫也是必然要掌握的一門學科。作為java初級和中級推薦一下,把高級也列進來是個人覺得,我們大部分人在工作中都只是在設計程序初始,會用到資料庫方面的知識:建庫、建表、索引、存儲過程等。殊不知,資料庫在系統中起著舉足輕重的作用,大到引起系統崩潰,小到頁面數據查詢異常等。值得重視!"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《Java與模式》"); search.setContent("適合對象:java初級、中級、高級;設計模式,可作為入門和進階的過渡學習;也可作為進階到高級的學習。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《重構:改善既有代碼的設計》"); search.setContent("適合對象:中級、高級;當你大大小小經歷了一些項目之後,想要針對某些項目做些改善或重構,那麼:這本書特別適合你。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《代碼整潔之道》"); search.setContent("適合對象:中級、高級;當你經歷了一些項目,也擼了(複製+粘貼)不少代碼之後;你要做的是要想辦法提升你寫的代碼的效率和性能以及整潔等。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《HTTP權威指南》"); search.setContent("適合對象:中級、高級;這本書可以讓你對http通信機制原理,網絡傳輸方面來個一站式的學些。徹底掌握web開發過程中,通信機制原理和技術。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《jQuery基礎教程》"); search.setContent("適合對象:java初級、中級、高級;這些是作為學習Java Web開發來說,前端技術和框架的最好典範了。jq、js、xml等;雖然現在前端技術發展到vue、anglar那些了。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《Java並發編程實踐》"); search.setContent(" 適合對象:中級、高級;做大型高並發多線程系統時,必不可少的技術:並發編程。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《Spring實戰(第4版)》"); search.setContent(" 適合對象:中級、高級;高級階段,必須學會使用並掌握web框架的原理和技術知識;Spring作為web框架中重中之重。是必須要掌握的技術。"); search.setCreateTime("2020-09-13"); searchDao.save(search);
search.setTitle("《深入理解Java 虛擬機 第2版》"); search.setContent("適合對象:中級、高級;一個合格的java程式設計師,對jvm深層原理如果不了解;甚至很陌生。那麼,想要在這條道路上繼續深入發展的話。趕緊學一學jvm的原理知識吧。"); search.setCreateTime("2020-09-13");        searchDao.save(search); }}

--完--

為了方便大家更好的學習,本公眾號經常分享一些完整的單個功能案例代碼給大家去練習,如果本公眾號沒有你要學習的功能案例,你可以聯繫小編(微信:xxf960513)提供你的小需求給我,我安排我們這邊的開發團隊免費幫你完成你的案例。
注意:只能提單個功能的需求不能要求功能太多,比如要求用什麼技術,有幾個頁面,頁面要求怎麼樣?

請長按識別二維碼

想學習更多的java功能案例請關注

如果你覺得這個案例以及我們的分享思路不錯,對你有幫助,請分享給身邊更多需要學習的朋友。別忘了《留言+點在看》給作者一個鼓勵哦!

相關焦點

  • springboot整合elasticsearch全文檢索入門
    //請與spring-boot-starter-data-elasticsearch的jar包版本一致compile('org.elasticsearch.client:transport:5.6.11') springBoot 2.0.5.RELEASE 起步依賴的elasticsearch的版本是 5.6.11 # 配置1.
  • 基於 ElasticSearch 實現站內全文搜索
    在國內的如百度這樣的搜尋引擎也屬於這個領域,要自己實現一個搜尋引擎是非常難的,不過信息查找對每一個公司都非常重要,對於開發人員也可以選則一些市場上的開源項目來構建自己的站內搜尋引擎,本文將通過ElasticSearch來構建一個這樣的信息檢索項目。1 技術選型1.1 ElasticSearchElasticsearch是一個基於Lucene的搜索伺服器。
  • 全文搜尋引擎Elasticsearch入門教程
    全文搜索屬於最常見的需求,開源的 Elasticsearch (以下簡稱 Elastic)是目前全文搜尋引擎的首選。
  • 實戰:Nodejs+Mongodb+Elasticsearch 實現簡單的搜索
    在網站建立初期,我們提供的搜索服務很多都是基於資料庫的模糊搜索,在性能和可用性上多少會有所缺失,所以在網站發展壯大後,就不得不增強搜索功能。elasticsearch 的基本功能就已經足夠一般的搜索需求。本文將介紹,如何使用 nodejs + mongodb + es 實現一個簡單而強大的全文搜索功能,以提高網站搜索體驗。
  • Spring Boot系列(十)Spring Boot整合Elasticsearch全文搜尋引擎
    全文搜尋引擎,需要springboot實戰完整視頻教程的,點擊這裡!Elastic Search是一個開源的,分布式,實時搜索和分析引擎。Spring Boot為Elasticsearch及Spring Data Elasticsearch提供的基於它的抽象提供了基本的配置。
  • 深入淺出 spring-data-elasticsearch - 實戰案例詳解(四)
    比如電商網站的搜索,搜到商品名稱和商品描述,自然商品名稱的權重遠遠大於商品描述。而且單詞匹配肯定不如短語匹配。這樣就出現了新的需求,如何確定這些短語,即自然分詞。那就利用分詞器,即可得到所需要的短語,然後進行搜索。下面介紹短語如何進行按權重分匹配搜索。二、運行 spring-data-elasticsearch-query 工程1.
  • Elastic App Search 為應用無痛添加搜索功能
    開發搜索功能從此再也不用犯愁了,有了 App Search ,為應用增加搜索功能一下子變得簡單了很多。本文描述了如何輕鬆上手這套搜索平臺的所有步驟。什麼是 App Search? 這是一套強大的 API 和開發者工具集,以構建功能強大的面向用戶的搜索應用為目標。
  • 全文搜尋引擎 Elasticsearch 入門
    如有好文章投稿,請點擊 → 這裡了解詳情全文搜索屬於最常見的需求,開源的 Elasticsearch (以下簡稱 Elastic)是目前全文搜尋引擎的首選。 $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip $ unzip elasticsearch-5.5.1.zip $ cd elasticsearch-5.5.1/ 接著,進入解壓後的目錄,運行下面的命令,啟動 Elastic
  • SpringBoot 操作 ElasticSearch 詳解
    它提供了一個分布式多員工能力的全文搜尋引擎,基於 RESTful web 接口。Elasticsearch 是用 Java 語言開發的,並作為 Apache 許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。ElasticSearch 用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
  • 全文搜尋引擎 Elasticsearch 入門教程
    如有好文章投稿,請點擊 → 這裡了解詳情全文搜索屬於最常見的需求,開源的 Elasticsearch (以下簡稱 Elastic)是目前全文搜尋引擎的首選。 $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip $ unzip elasticsearch-5.5.1.zip $ cd elasticsearch-5.5.1/ 接著,進入解壓後的目錄,運行下面的命令,啟動 Elastic
  • 知乎Live全文搜索之使用Elasticsearch做搜索建議
    本來這篇應該是基於Sanic的異步API後端了,過年時突然覺得應該做一個自動補全(suggest)搜索的功能,而且正好有公眾號讀者想了解我的ES環境的搭建過程,今天再鋪墊一篇。Elasticsearch環境搭建我有記錄筆記到Evernote的習慣,正好拿出來。
  • SpringBoot 操作 ElasticSearch 詳解(萬字長文)
    它提供了一個分布式多員工能力的全文搜尋引擎,基於 RESTful web 接口。Elasticsearch 是用 Java 語言開發的,並作為 Apache 許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。ElasticSearch 用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
  • 全網必會的搜索技術-ElasticSearch(一)
    或者說只要業務系統需要做搜索功能的,或者日誌收集的都會用到該技術。故此筆者發奮圖強,花了半個月的時間,徹底學透ElasticSearch這門技術。這門技術涉及到很多知識點,筆者打算分多篇文章來講解這門技術。
  • 深入淺出 spring-data-elasticsearch - 基本案例詳解(三)
    後臺起守護線程啟動 Elasticsearchcd elasticsearch-2.3.2/./bin/elasticsearch -dgit clone 下載工程 springboot-elasticsearch ,項目地址見 GitHub - https://github.com/JeffLi1993/ ... ample。
  • Elasticsearch專題
    ,基於RESTful風格的全文搜尋引擎ES是分布式文檔資料庫。數據量擴展到很大級別(PB級數據)ES高可用和高可擴展而生https://www.elastic.co/cn/https://www.elastic.co/products/elasticsearch
  • 芋道 Spring Boot Elasticsearch 入門
    keyword=華為手機 搜索功能,需要支持關鍵字、分類、品牌等等,並且可以按照綜合、銷量等等升降序排序,那麼我們就無法在上面看到的 Spring Data Repository 提供的簡單的查詢方法,而需要使用到 ElasticsearchRepository 的 search 方法,代碼如下:// ElasticsearchRepository.java
  • elasticsearch入門實戰
    1.介紹Elasticsearch 是一個高度可擴展的開源全文搜索和分析引擎。
  • ElasticSearch 極簡教程
    平時我們在 GitHub 上進行搜索的時候,Github 不僅可以幫我們找到相隔的代碼產庫,還可以幫助實現代碼級的搜索及搜索詞的高亮的顯示,。當你在網上購物的時候,它也可以幫助你做商品的推薦。國外:Wikipedia(維基百科)使用 ES 提供全文搜索並高亮關鍵字、Stack Overflow(IT問答網站)結合全文搜索與地理位置查詢、Github使用Elasticsearch檢索1300億行的代碼5.
  • ElasticSearch安裝
    一、ElasticSearch介紹Elasticsearch是一個基於Lucene[1]的搜索伺服器。
  • SpringBoot+Elasticsearch實戰
    環境與配置服務端:elasticsearch-6.3.2    1臺客戶端:elasticsearch 6.4.1服務端配置文件:elasticsearch.ymlcluster.name>6.4.1</elasticsearch.version>        <spring.data.elasticsearch.version>3.1.0.RELEASE</spring.data.elasticsearch.version>    </properties>    <dependencies