近幾篇ElasticSearch系列:css
一、阿里雲服務器Linux系統安裝配置ElasticSearch搜索引擎html
二、Linux系統中ElasticSearch搜索引擎安裝配置Head插件前端
三、ElasticSearch搜索引擎安裝配置中文分詞器IK插件java
四、ElasticSearch搜索引擎安裝配置拼音插件pinyinjquery
五、ElasticSearch搜索引擎在JavaWeb項目中的應用 web
1、前言ajax
前四篇簡單介紹了ElasticSearch(如下簡稱ES)在阿里雲服務器Linux系統上的部署配置等。本篇將簡述一下ES在JavaWeb項目中的應用。本項目前端框架是Vue.js,先後端數據交互採用是經常使用的SSM框架,項目管理工具爲Maven,ES爲6.3.2版本。spring
2、正文json
一、ES在Maven中添加相應依賴,以下所示:後端
1 <dependency> 2 <groupId>org.elasticsearch</groupId> 3 <artifactId>elasticsearch</artifactId> 4 <version>6.3.2</version> 5 </dependency> 6 <dependency> 7 <groupId>org.elasticsearch.client</groupId> 8 <artifactId>transport</artifactId> 9 <version>6.3.2</version> 10 </dependency>
二、@Configuration註解新建的 「ElasticSearchConfig」 類,用來初始化ES客戶端TransportClient鏈接,經過setting來建立,若不指定則默認連接的集羣名爲elasticsearch,以下圖所示:
1 @Configuration 2 public class ElasticSearchConfig { 3 4 @Bean 5 public TransportClient client() throws UnknownHostException { 6 Settings settings = Settings.builder().build(); 7 TransportClient client = new PreBuiltTransportClient(settings) 8 .addTransportAddress(new TransportAddress(InetAddress.getByName("部署ES的IP地址"), 9300)); 9 return client; 10 } 11 }
三、jsp裏首先須要導入jquery與Vue,而後css樣式僅供參考,以下圖所示:
1 <div id="search_main" style="position: relative;top: -360px;left: -200px;width: 100%;height: 50px;text-align: center"> 2 <input id="search_input1" type="text" name="search1" placeholder="請輸入企業名稱。如「阿里巴巴」或「alibaba」" 3 style="height: 50px;width: 720px;border: none;font-size: 18px;" onkeypress="EnterPress(event)" onkeydown="EnterPress()" 4 v-model="searchText" v-on:keyup="showName(searchText)"/> 5 <img id="voice" src="icon/voice1.png" width="35" height="35" style="position: absolute;left: 1145px;top: 7px;"/> 6 <button id="search_button1" type="button" style="position: relative;left: -4px;top: 1px;height: 50px;width: 100px;border: none;background-color: #1db5ee"> 7 <font size="4" color="white" style="align-content: center">搜索</font> 8 </button> 9 <font id="searchType" style="display: none">企業名</font> 10 <div id="parentRelationSearch" v-for="(company, cIndex) in companyList" style="position: relative;top: 0px;left: 474px;height: auto;width: 719px;background-color: #ffffff;z-index: 99"> 11 <div class="relationSearch" v-on:click="putVal(company.name)" v-on:mouseenter="mouseEnter($event)" v-on:mouseleave="mouseLeave($event)" style="position: relative;top: 0px;left: 0px;width: 100%;height: 35px;border-bottom: 1px solid #e8e8e8;line-height: 35px;"> 12 <font size="2" style="position: absolute;left: 5px">{{company.name}}</font> 13 <font size="1.5" style="position: absolute;left: 92%;">{{company.score}}</font> 14 </div> 15 </div> 16 </div>
四、id爲search_main的元素爲Vue實例掛載的元素節點,以及showName函數(ajax請求)爲keyup事件,putVal函數(將用戶選中的元素值賦值給搜索框)爲click事件,mouseEnter、mouseLeave函數分別爲mouseenter、mouseleave事件,以下圖所示:
1 var vm1 = new Vue({ 2 el: '#search_main', 3 data: { 4 searchText: "", 5 companyList: [], 6 }, 7 mounted: function () { 8 this.showName(); 9 this.putVal(); 10 this.mouseEnter(); 11 this.mouseLeave(); 12 }, 13 methods: { 14 putVal: function (val) { 15 $("#search_input1").val(val); 16 $(".relationSearch").hide(); 17 document.getElementById("search_input1").focus(); 18 }, 19 showName: function (key) { 20 console.log(key); 21 if (key.length != 0) { 22 var searchType = document.getElementById("searchType").innerText; 23 if (searchType == "所有" || searchType == "企業名") { 24 $(".relationSearch").show(); 25 var _this = this; 26 this.$http.get("auto_think.do?key=" + key).then(function (jsonResult) { 27 _this.companyList = (jsonResult.body); 28 }); 29 } 30 } else { 31 $(".relationSearch").hide(); 32 } 33 }, 34 mouseEnter: function ($event) { 35 $event.currentTarget.className = "relationSearch searchActive"; 36 }, 37 mouseLeave: function ($event) { 38 $event.currentTarget.className = "relationSearch"; 39 } 40 } 41 });
上述mouseEnter函數是用於動態添加class,用以實現鼠標移入則修改元素的背景功能:
1 .searchActive{ 2 background-color:#e8e8e8; 3 }
五、QueryBuilder是ES提供的一個查詢接口,進行單個匹配值爲key的文檔。SearchRequestBuilder根據索引與類型構造查詢請求,設置查詢條件和分頁參數,再獲取返回值並進行處理,最後返回,以下圖所示:
1 package controller; 2 3 import entity.ElasticSearchResult; 4 import org.elasticsearch.action.index.IndexResponse; 5 import org.elasticsearch.action.search.SearchRequestBuilder; 6 import org.elasticsearch.action.search.SearchResponse; 7 import org.elasticsearch.client.transport.TransportClient; 8 import org.elasticsearch.common.xcontent.XContentBuilder; 9 import org.elasticsearch.common.xcontent.XContentFactory; 10 import org.elasticsearch.index.query.QueryBuilder; 11 import org.elasticsearch.index.query.QueryBuilders; 12 import org.elasticsearch.search.SearchHit; 13 import org.elasticsearch.search.SearchHits; 14 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.stereotype.Controller; 16 import org.springframework.web.bind.annotation.GetMapping; 17 import org.springframework.web.bind.annotation.RequestParam; 18 import org.springframework.web.bind.annotation.ResponseBody; 19 20 import java.io.IOException; 21 import java.math.BigDecimal; 22 import java.util.ArrayList; 23 import java.util.List; 24 25 @Controller 26 public class ElasticSearchController { 27 28 @Autowired 29 private TransportClient client; 30 31 //搜索自動聯想 32 @GetMapping("/auto_think.do") 33 @ResponseBody 34 public List<ElasticSearchResult> findIndexRecordByName(@RequestParam(name = "key") String key) { 35 // 構造查詢請求 36 QueryBuilder bq = QueryBuilders.matchQuery("name.pinyin", key); 37 SearchRequestBuilder searchRequest = client.prepareSearch("medcl").setTypes("folks"); 38 39 // 設置查詢條件和分頁參數 40 int start = 0; 41 int size = 5; 42 searchRequest.setQuery(bq).setFrom(start).setSize(size); 43 44 // 獲取返回值,並進行處理 45 SearchResponse response = searchRequest.execute().actionGet(); 46 SearchHits shs = response.getHits(); 47 List<ElasticSearchResult> esResultList = new ArrayList<>(); 48 for (SearchHit hit : shs) { 49 ElasticSearchResult esResult = new ElasticSearchResult(); 50 double score = hit.getScore(); 51 BigDecimal b = new BigDecimal(score); 52 score = b.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue(); 53 String name = (String) hit.getSourceAsMap().get("name"); 54 System.out.println("score:" + score + "name:" + name); 55 esResult.setScore(score); 56 esResult.setName(name); 57 esResultList.add(esResult); 58 } 59 return esResultList; 60 } 61 62 }
下述爲ElasticSearchResult實體類:
1 package entity; 2 3 public class ElasticSearchResult { 4 5 private double score; 6 7 private String name; 8 9 public ElasticSearchResult() { 10 } 11 12 public double getScore() { 13 return score; 14 } 15 16 public void setScore(double score) { 17 this.score = score; 18 } 19 20 public String getName() { 21 return name; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 }
再附上向指定索引與類型添加、刪除、更新文檔函數代碼,以下所示:
1 /** 2 * 添加文檔 3 * @param name 4 */ 5 public void addByName(String name) { 6 try { 7 XContentBuilder content = XContentFactory.jsonBuilder() 8 .startObject().field("name", name).endObject(); 9 client.prepareIndex("medcl", "folks") 10 .setSource(content).get(); 11 System.out.println("ElasticSearch添加文檔成功。"); 12 } catch (IOException e) { 13 System.out.println("ElasticSearch添加文檔出錯。"); 14 e.printStackTrace(); 15 } 16 } 17 18 /** 19 * 刪除文檔 20 * @param name 21 */ 22 public void deleteByName(String name) { 23 BulkRequestBuilder bulkRequest = client.prepareBulk(); 24 SearchResponse response = client.prepareSearch("medcl").setTypes("folks") 25 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) 26 .setQuery(QueryBuilders.termQuery("name", name)) 27 .setFrom(0).setSize(20).setExplain(true).execute().actionGet(); 28 for(SearchHit hit : response.getHits()){ 29 String id = hit.getId(); 30 bulkRequest.add(client.prepareDelete("medcl", "folks", id).request()); 31 } 32 BulkResponse bulkResponse = bulkRequest.get(); 33 34 if (bulkResponse.hasFailures()) { 35 System.out.println("ElasticSearch刪除文檔出錯。"); 36 for(BulkItemResponse item : bulkResponse.getItems()){ 37 System.out.println(item.getFailureMessage()); 38 } 39 }else { 40 System.out.println("ElasticSearch刪除文檔成功。"); 41 } 42 } 43 44 /** 45 * 更新文檔 46 * @param beforeName 47 * @param afterName 48 */ 49 public void updateByName(String beforeName,String afterName){ 50 SearchResponse response = client.prepareSearch("medcl").setTypes("folks") 51 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) 52 .setQuery(QueryBuilders.termQuery("name", beforeName)) 53 .setFrom(0).setSize(20).setExplain(true).execute().actionGet(); 54 try { 55 for(SearchHit hit : response.getHits()){ 56 UpdateRequest updateRequest = new UpdateRequest(); 57 updateRequest.index("medcl"); 58 updateRequest.type("folks"); 59 updateRequest.id(hit.getId()); 60 updateRequest.doc(XContentFactory.jsonBuilder().startObject().field("name",afterName).endObject()); 61 client.update(updateRequest).get(); 62 } 63 System.out.println("ElasticSearch更新文檔成功。"); 64 }catch (Exception e){ 65 System.out.println("ElasticSearch更新文檔出錯。"); 66 e.printStackTrace(); 67 } 68 }
最後附上功能演示效果圖,以下圖所示:
至此是對ElasticSearch搜索引擎在JavaWeb項目中的應用的一個簡單介紹。
若有疏漏錯誤之處,還請不吝賜教!