優質文章,及時送達
前端: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: activepackage 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功能案例請關注
如果你覺得這個案例以及我們的分享思路不錯,對你有幫助,請分享給身邊更多需要學習的朋友。別忘了《留言+點在看》給作者一個鼓勵哦!