ElasticSearch搜索引擎在JavaWeb項目中的應用

近幾篇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項目中的應用的一個簡單介紹。

若有疏漏錯誤之處,還請不吝賜教!

相關文章
相關標籤/搜索