本篇內(nèi)容介紹了“怎么在自己的項目中引入ElasticSearch搜索引擎”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
專業(yè)從事企業(yè)網(wǎng)站建設(shè)和網(wǎng)站設(shè)計服務(wù),包括網(wǎng)站建設(shè)、空間域名、網(wǎng)站空間、企業(yè)郵箱、微信公眾號開發(fā)、微信支付寶微信小程序定制開發(fā)、重慶APP軟件開發(fā)、軟件開發(fā)、等服務(wù)。公司始終通過不懈的努力和以更高的目標(biāo)來要求自己,在不斷完善自身管理模式和提高技術(shù)研發(fā)能力的同時,大力倡導(dǎo)推行新經(jīng)濟品牌戰(zhàn)略,促進互聯(lián)網(wǎng)事業(yè)的發(fā)展。
在大多數(shù)系統(tǒng)中,都需要支持搜索的功能,以簡單博客系統(tǒng)為例,雖然說MySQL也可以通過模糊查詢匹配到對應(yīng)的數(shù)據(jù),但是效率實在太低。這個時候就需要拿出分布式搜索引擎ElasticSearch了。本博客重點在于ES的集成使用,因此前端采用最簡單的方式呈現(xiàn),大家只需要關(guān)注后端邏輯即可。(本博客基于ES7.6.1,和ES6.X版本有較大差異)
依賴主要就是web、es以及thymleaf相關(guān):
org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.alibaba fastjson 1.2.76 org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf thymeleaf-spring5 org.thymeleaf.extras thymeleaf-extras-java8time
編寫ES的配置類,編寫連接信息,之后直接通過Autowired連接即可:
@Configuration public class ElasticSearchConfig { @Bean public RestHighLevelClient restHighLevelClient(){ RestHighLevelClient client=new RestHighLevelClient( RestClient.builder( new HttpHost("192.168.78.128",9200,"http") ) ); return client; } }
編寫一個類用來存儲要存儲的數(shù)據(jù),我這里為了演示只在es中插入標(biāo)題和作者的信息
@Data @AllArgsConstructor public class BlogDO { private String title; private String author; }
最后新建一個IndexController和IndexService以及IndexServiceImpl,接下來會使用。最終的目錄結(jié)構(gòu)如下:
要做數(shù)據(jù)的搜索,首先第一步就是數(shù)據(jù)的導(dǎo)入。在真實的業(yè)務(wù)場景中,數(shù)據(jù)的導(dǎo)入有很多方式。一種是當(dāng)新增數(shù)據(jù)時在代碼邏輯中做增量的導(dǎo)入操作,或者是由數(shù)倉團隊負(fù)責(zé)數(shù)據(jù)的增量導(dǎo)入。我接觸到的業(yè)務(wù)中,后端程序員不需要去關(guān)注導(dǎo)入的操作,這個步驟是數(shù)倉團隊做的。
在我們個人的博客系統(tǒng)中,可以在新增博客后立刻同步數(shù)據(jù)到ES,也可以先通過消息中間件發(fā)送一條消息,消費者定期去讀取消息新增數(shù)據(jù)。
這里演示就直接導(dǎo)入了:
@Controller public class IndexController { @Autowired private IndexService indexService; @ResponseBody @GetMapping("/prepareData") public String prepareData(){ String result=indexService.prepareData(); return result; } }
具體的service實現(xiàn)如下:
@Service public class IndexServiceImpl implements IndexService { @Autowired private RestHighLevelClient restHighLevelClient; @Override public String prepareData() { ListblogDOS = new ArrayList<>(); blogDOS.add(new BlogDO("ElasticSearch究竟是個什么東西", "Java魚仔")); blogDOS.add(new BlogDO("SpringBoot+SpringSecurity實現(xiàn)基于真實數(shù)據(jù)的授權(quán)認(rèn)證", "Java魚仔")); blogDOS.add(new BlogDO("Dubbo兩小時快速上手教程(直接代碼、Spring、SpringBoot)", "Java魚仔")); blogDOS.add(new BlogDO("淺析五種最常用的Java加密算法", "Java魚仔")); blogDOS.add(new BlogDO("Java程序員需要知道的操作系統(tǒng)知識匯總", "Java魚仔")); blogDOS.add(new BlogDO("一步步教你如何在SpringBoot項目中引入支付功能", "Java魚仔")); blogDOS.add(new BlogDO("Zookeeper實現(xiàn)分布式鎖的原理是什么?", "Java魚仔")); blogDOS.add(new BlogDO("一個成熟的Java項目如何優(yōu)雅地處理異常", "Java魚仔")); blogDOS.add(new BlogDO("基于SpringBoot實現(xiàn)文件的上傳下載", "Java魚仔")); blogDOS.add(new BlogDO("如何用Java寫一個規(guī)范的http接口?", "Java魚仔")); BulkRequest bulkRequest = new BulkRequest(); bulkRequest.timeout("10s"); blogDOS.stream().forEach(x -> { bulkRequest.add(new IndexRequest("blog_index").source(JSON.toJSONString(x), XContentType.JSON)); }); BulkResponse responses=null; try { responses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } return String.valueOf(responses.status()); } }
我選取了自己的幾篇博客文章,多執(zhí)行幾次接口,保證ES中有幾十條數(shù)據(jù)供測試使用即可。
接下來就是搜索的過程了,搜索的邏輯其實比較簡單,具體的代碼就按照上一篇博客中的方式來編寫,在真實業(yè)務(wù)場景中,每個公司可能會有自己的封裝搜索方法:
IndexController中增加一個方法:
@GetMapping("/search") public String search(@RequestParam("keywords")String keywords, @RequestParam("pageNum")String pageNum, @RequestParam("pageSize")String pageSize, Model model){ List
具體實現(xiàn)類中增加方法:
@Override public List
簡單寫一個前端頁面
Title
跑起來看一下,訪問
http://localhost:8080/search?keywords=Java&pageNum=1&pageSize=10
在鏈接中,我關(guān)鍵詞填了Java,pageNum是1,每頁展示10行,可以看到和Java相關(guān)的數(shù)據(jù)就被查出來了。
在百度搜索Java時,可以看到查詢出來的Java被高亮顯示了,之前在講ES語法的時候,我們也知道了ES支持高亮查詢,下面就通過代碼來實現(xiàn)。
稍微修改一下搜索的代碼,增加高亮配置,在返回值中用高亮字符串替換原來的字符串。
public List> searchHighLightData(String keywords, int pageNum, int pageSize){ if (pageNum<1){ pageNum=1; } SearchRequest request = new SearchRequest("blog_index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.from(pageNum); searchSourceBuilder.size(pageSize); //高亮構(gòu)造器 HighlightBuilder highlightBuilder=new HighlightBuilder(); //高亮查詢字段 highlightBuilder.field("title"); //是否將所有匹配到的字段高亮顯示,false表示只顯示一個 highlightBuilder.requireFieldMatch(false); //高亮的標(biāo)簽 highlightBuilder.preTags(""); highlightBuilder.postTags(""); searchSourceBuilder.highlighter(highlightBuilder); MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", keywords); searchSourceBuilder.query(matchQueryBuilder); searchSourceBuilder.timeout(new TimeValue(10, TimeUnit.SECONDS)); request.source(searchSourceBuilder); SearchResponse search=null; try { search = restHighLevelClient.search(request, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } List > result=new ArrayList(); SearchHit[] hits = search.getHits().getHits(); //遍歷結(jié)果,將高亮返回值title替換到原來的title中 for (SearchHit searchHit:hits){ Map sourceAsMap = searchHit.getSourceAsMap(); Map highlightFields = searchHit.getHighlightFields(); HighlightField title = highlightFields.get("title"); if (title!=null){ StringBuilder highLightTitle=new StringBuilder(); Text[] texts = title.fragments(); for(Text text:texts){ highLightTitle.append(text); } sourceAsMap.put("title",highLightTitle); } result.add(sourceAsMap); } return result; }
繼續(xù)訪問
http://localhost:8080/search?keywords=Java&pageNum=1&pageSize=10,
通過斷點可以看到,搜索的關(guān)鍵詞已經(jīng)被我們設(shè)置的span標(biāo)簽包住了。
在前端thymeaf中,我是用了th:utext,這個標(biāo)簽可以將Html解析,最終的高亮顯示如下:
“怎么在自己的項目中引入ElasticSearch搜索引擎”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!