springboot整合ES

(2020/4/19對本文進行補充)關於springboot整個es有四種方法,分別是TransportClient、RestClient、SpringData-Es、Elasticsearch-SQL。html

官方推薦的是RestClient,我在工做中見到的是SpringData-ES,這裏舉的例子是TransportClient。java

也就是說 ↓ ↓ ↓node

若是是TransportClient,能夠參考這篇文章。mysql

若是使用的是RestClient,能夠參考這篇文章:https://www.jianshu.com/p/2ff05a83816e;這種方式也是官網推薦的;web

若是使用的是SpringData-Es,能夠參考:https://blog.csdn.net/tianyaleixiaowu/article/details/76149547/ (介紹了ElasticsearchRepoistory和ElasticsearchTemplate兩種方法的具體使用。);spring

若是使用的是Elasticsearch-SQL,面向百度,我確實太懶了,sql

一、新建一個maven項目數據庫

二、導入相應的jar包apache

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0"
  3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5     <modelVersion>4.0.0</modelVersion>
  6 
  7     <groupId>com.aaa.liu.es</groupId>
  8     <artifactId>SpringBootEs</artifactId>
  9     <version>1.0-SNAPSHOT</version>
 10 
 11     <parent>
 12         <groupId>org.springframework.boot</groupId>
 13         <artifactId>spring-boot-starter-parent</artifactId>
 14         <version>1.5.10.RELEASE</version>
 15     </parent>
 16 
 17     <!--
 18         !!!!!!!導入springboot自帶的es jar包: es-starter
 19         (不能使用springboot自帶的)!!!!!!!
 20 
 21         es的jar包
 22         trasportClient jar包(就是使用Java代碼對ES進行增刪改查)
 23         使用es的時候es會自動依賴log4j,若是沒有log4j的jar包,會報錯可是不影響項目正常運行(有強迫症的同窗能夠導入log4j)
 24         es還會自動依賴common-lang3(基於Java.lang包中作的一層封裝,比Java.lang包功能更強大)
 25         springboot
 26         web-starter
 27         mybatis
 28         mysql
 29         druid
 30         configuration-properties == true(@ConfigurationProperties:從properties中讀取配置信息)
 31 
 32     -->
 33 
 34     <dependencies>
 35         <!--
 36             springboot-starter-web
 37         -->
 38         <dependency>
 39             <groupId>org.springframework.boot</groupId>
 40             <artifactId>spring-boot-starter-web</artifactId>
 41         </dependency>
 42         <!--
 43             springboot-mybatis整合包
 44         -->
 45         <dependency>
 46             <groupId>org.mybatis.spring.boot</groupId>
 47             <artifactId>mybatis-spring-boot-starter</artifactId>
 48             <version>1.3.0</version>
 49         </dependency>
 50         <!--
 51             mysql的驅動包
 52         -->
 53         <dependency>
 54             <groupId>mysql</groupId>
 55             <artifactId>mysql-connector-java</artifactId>
 56             <version>5.1.38</version>
 57         </dependency>
 58         <!--
 59             druid鏈接池
 60         -->
 61         <dependency>
 62             <groupId>com.alibaba</groupId>
 63             <artifactId>druid</artifactId>
 64             <version>1.1.10</version>
 65         </dependency>
 66         <!--
 67             html的thymeleaf模板
 68         -->
 69         <dependency>
 70             <groupId>org.springframework.boot</groupId>
 71             <artifactId>spring-boot-starter-thymeleaf</artifactId>
 72         </dependency>
 73 
 74         <!--
 75             fastjson包
 76         -->
 77         <dependency>
 78             <groupId>com.fasterxml.jackson.core</groupId>
 79             <artifactId>jackson-databind</artifactId>
 80             <version>2.8.1</version>
 81         </dependency>
 82 
 83         <dependency>
 84             <groupId>org.elasticsearch</groupId>
 85             <artifactId>elasticsearch</artifactId>
 86             <version>6.4.0</version>
 87         </dependency>
 88 
 89         <dependency>
 90             <groupId>org.elasticsearch.client</groupId>
 91             <artifactId>transport</artifactId>
 92             <version>6.4.0</version>
 93             <exclusions>
 94                 <exclusion>
 95                     <groupId>org.elasticsearch</groupId>
 96                     <artifactId>elasticsearch</artifactId>
 97                 </exclusion>
 98             </exclusions>
 99         </dependency>
100 
101         <dependency>
102             <groupId>org.apache.commons</groupId>
103             <artifactId>commons-lang3</artifactId>
104             <version>3.4</version>
105         </dependency>
106 
107         <dependency>
108             <groupId>commons-httpclient</groupId>
109             <artifactId>commons-httpclient</artifactId>
110             <version>3.1</version>
111         </dependency>
112 
113         <!--<dependency>
114             <groupId>org.springframework.boot</groupId>
115             <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
116         </dependency>-->
117 
118         <dependency>
119             <groupId>org.springframework.boot</groupId>
120             <artifactId>spring-boot-configuration-processor</artifactId>
121             <optional>true</optional>
122         </dependency>
123 
124         <dependency>
125             <groupId>org.apache.logging.log4j</groupId>
126             <artifactId>log4j-core</artifactId>
127             <version>2.9.1</version>
128         </dependency>
129         <dependency>
130             <groupId>org.apache.logging.log4j</groupId>
131             <artifactId>log4j-api</artifactId>
132             <version>2.9.1</version>
133         </dependency>
134     </dependencies>
135 
136 </project>

 

注意:這裏不能加入springboot自帶的es-starter 的jar包,不然會報錯:org.elasticsearch.action.count.CountRequestBuilderjson

 

三、開始springboot項目的架構:

  包:controller、Mapper、service、model、utils、config、status(枚舉)

  入口類:ApplicationRun

  resources:包:config、Mapper

 

[1]  開始咱們基本的配置:resources/config/application.properties:

 1 server.port=8081
 2 server.context-path=/
 3 
 4 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
 5 spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
 6 spring.datasource.username=root
 7 spring.datasource.password=123456
 8 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
 9 
10 mybatis.type-aliases-package=com.aaa.liu.es.model
11 mybatis.mapper-locations=classpath:mapper/*Mapper.xml
12 
13 elasticsearch.ip=192.168.134.147
14 # 若是使用的TransportClient方式進行鏈接ES,必需要使用9300端口號,使用9200端口號沒法鏈接
15 elasticsearch.port=9300
16 # ES的鏈接數(能夠同時有多少鏈接)
17 elasticsearch.pool=5
18 # 注意cluster.name須要與config/elasticsearch.yml中的cluster.name對應一致
19 elasticsearch.clusterName=my-application
20 elasticsearch.nodeName=node-1

 

 

[2]  將咱們的配置信息調用:java中的config:  ESProperties類和EsConfig

 1 package com.aaa.liu.es.config;
 2 
 3 import org.springframework.boot.context.properties.ConfigurationProperties;
 4 import org.springframework.stereotype.Component;
 5 
 6 /**
 7  * @Author 劉其佳
 8  * @DateTime 2019/9/18 19:31
 9  * @Project_Name SpringBootEs
10  */
11 
12 @Component
13 @ConfigurationProperties(prefix = "elasticsearch")
14 public class ESProperties {
15 
16     private String ip;
17     private String port;
18     private String pool;
19     private String clusterName;
20     private String nodeName;
21 
22     public String getIp() {
23         return ip;
24     }
25 
26     public void setIp(String ip) {
27         this.ip = ip;
28     }
29 
30     public String getPort() {
31         return port;
32     }
33 
34     public void setPort(String port) {
35         this.port = port;
36     }
37 
38     public String getPool() {
39         return pool;
40     }
41 
42     public void setPool(String pool) {
43         this.pool = pool;
44     }
45 
46     public String getClusterName() {
47         return clusterName;
48     }
49 
50     public void setClusterName(String clusterName) {
51         this.clusterName = clusterName;
52     }
53 
54     public String getNodeName() {
55         return nodeName;
56     }
57 
58     public void setNodeName(String nodeName) {
59         this.nodeName = nodeName;
60     }
61 }

 

 

 1 package com.aaa.liu.es.config;
 2 
 3 import org.elasticsearch.client.transport.TransportClient;
 4 import org.elasticsearch.common.settings.Settings;
 5 import org.elasticsearch.common.transport.TransportAddress;
 6 import org.elasticsearch.transport.client.PreBuiltTransportClient;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.boot.autoconfigure.SpringBootApplication;
 9 import org.springframework.context.annotation.Bean;
10 
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 
14 /**
15  * @Author 劉其佳
16  * @DateTime 2019/9/18 19:33
17  * @Project_Name SpringBootEs
18  */
19 @SpringBootApplication
20 public class EsConfig {
21 
22     @Autowired
23     private ESProperties esProperties;
24 
25 
26     /**
27     * @author 劉其佳
28     * @description
29      *      建立並初始化TransportClient對象,使用該對象對ES進行增刪查改
30      *      cluster.name:集羣名字
31      *      node.name:節點名字
32      *      client.transport.sniff:客戶端(Java項目)一致監視ES的節點狀態(節點數),再也不須要手動添加節點,若是有新的節點產生了,會自動加載進項目中
33      *      thread_pool.search.size:線程池
34      *
35     * @param * param *:
36     * @date 2019/9/18
37     * @return org.elasticsearch.client.transport.TransportClient
38     * @throws
39     */
40     @Bean("transportClient")
41     public TransportClient getTransportClient(){
42         //一、建立TransportClient對象
43         TransportClient transportClient=null;
44         try{
45             //二、設置Java對ES的集羣信息
46             Settings settings=Settings.builder().put("cluster.name",esProperties.getClusterName())
47                     .put("node.name", esProperties.getNodeName())
48                     .put("client.transport.sniff", true)
49                     .put("thread_pool.search.size", esProperties.getPool()).build();
50             //三、初始化TransportClient對象
51             transportClient=new PreBuiltTransportClient(settings);
52             //四、配置對ES的鏈接信息
53             TransportAddress transportAddress=new TransportAddress(InetAddress.getByName(esProperties.getIp()),Integer.parseInt(esProperties.getPort()));
54             //五、把對ES的鏈接對象放到transportClient對象中
55             transportClient.addTransportAddress(transportAddress);
56         }catch (UnknownHostException e){
57             e.printStackTrace();
58         }
59         return transportClient;
60     }
61 }

 

 

四、主要的核心其實在utils包中的工具類:ESUtil

  1 package com.aaa.liu.es.utils;
  2 
  3 import com.aaa.liu.es.status.StatusEnum;
  4 import org.apache.commons.lang3.StringUtils;
  5 import org.elasticsearch.action.ActionFuture;
  6 import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
  7 import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
  8 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
  9 import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
 10 import org.elasticsearch.action.delete.DeleteResponse;
 11 import org.elasticsearch.action.get.GetRequestBuilder;
 12 import org.elasticsearch.action.get.GetResponse;
 13 import org.elasticsearch.action.index.IndexResponse;
 14 import org.elasticsearch.action.search.SearchRequestBuilder;
 15 import org.elasticsearch.action.search.SearchResponse;
 16 import org.elasticsearch.action.update.UpdateRequest;
 17 import org.elasticsearch.action.update.UpdateResponse;
 18 import org.elasticsearch.client.transport.TransportClient;
 19 import org.elasticsearch.common.text.Text;
 20 import org.elasticsearch.index.query.QueryBuilder;
 21 import org.elasticsearch.search.SearchHit;
 22 import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
 23 import org.elasticsearch.search.sort.SortOrder;
 24 import org.springframework.beans.factory.annotation.Autowired;
 25 import org.springframework.stereotype.Component;
 26 
 27 import javax.annotation.PostConstruct;
 28 import java.lang.reflect.Field;
 29 import java.util.*;
 30 
 31 /**
 32  * @Author 劉其佳
 33  * @DateTime 2019/9/18 20:35
 34  * @Project_Name SpringBootEs
 35  */
 36 @Component
 37 public class ESUtil {
 38 
 39     @Autowired
 40     private TransportClient transportClient;
 41 
 42     /**
 43      * 由於該工具類中全部的方法都是靜態方法,靜態方法只能調用靜態變量
 44      *  因此使用@Autowired註解所注入進的對象靜態方法不能直接調用,由於static修飾的方式不能使用普通變量
 45      *  下面的@PostConstruct註解就是來解決了以上的問題
 46      */
 47     private static TransportClient client;
 48 
 49     private static Map<String, Object> resultMap = new HashMap<String, Object>();
 50 
 51     /**
 52      * @PostContruct是spring框架的註解 spring容器初始化的時候執行該方法
 53      */
 54     @PostConstruct
 55     public void init() {
 56         client = this.transportClient;
 57     }
 58 
 59     /**
 60      * 建立索引
 61      *
 62      * @param index
 63      * @return
 64      */
 65     public static Map<String, Object> createIndex(String index) {
 66         // isIndexExist:判斷索引是否存在
 67         if (!isIndexExist(index)) {
 68             resultMap.put("code", StatusEnum.EXIST.getCode());
 69             resultMap.put("msg", StatusEnum.EXIST.getMsg());
 70         }
 71         CreateIndexResponse indexresponse = client.admin().indices().prepareCreate(index).execute().actionGet();
 72         // indexresponse.isAcknowledged():建立索引是否成功,return Boolean類型(true:表示成功,false:失敗)
 73         if(indexresponse.isAcknowledged()) {
 74             resultMap.put("code", StatusEnum.OPRATION_SUCCESS.getCode());
 75             resultMap.put("msg", StatusEnum.OPRATION_SUCCESS.getMsg());
 76         } else {
 77             resultMap.put("code", StatusEnum.OPRATION_FAILED.getCode());
 78             resultMap.put("msg", StatusEnum.OPRATION_FAILED.getMsg());
 79         }
 80         return resultMap;
 81     }
 82 
 83     /**
 84      * 刪除索引
 85      *
 86      * @param index
 87      * @return
 88      */
 89     public static Map<String, Object> deleteIndex(String index) {
 90         if (!isIndexExist(index)) {
 91             resultMap.put("code", StatusEnum.EXIST.getCode());
 92             resultMap.put("msg", StatusEnum.EXIST.getMsg());
 93         }
 94         DeleteIndexResponse dResponse = client.admin().indices().prepareDelete(index).execute().actionGet();
 95         if (dResponse.isAcknowledged()) {
 96             resultMap.put("code", StatusEnum.OPRATION_SUCCESS.getCode());
 97             resultMap.put("msg", StatusEnum.OPRATION_SUCCESS.getMsg());
 98         } else {
 99             resultMap.put("code", StatusEnum.OPRATION_FAILED.getCode());
100             resultMap.put("msg", StatusEnum.OPRATION_FAILED.getMsg());
101         }
102         return resultMap;
103     }
104 
105     /**
106      * 判斷索引是否存在
107      *
108      * @param index
109      * @return
110      */
111     public static boolean isIndexExist(String index) {
112         IndicesExistsResponse inExistsResponse = client.admin().indices().exists(new IndicesExistsRequest(index)).actionGet();
113         return inExistsResponse.isExists();
114     }
115 
116     /**
117      * @Author: LX
118      * @Description: 判斷index下指定type是否存在
119      * @Date: 2018/11/6 14:46
120      * @Modified by:
121      */
122     public static boolean isTypeExist(String index, String type) {
123         return isIndexExist(index)
124                 ? client.admin().indices().prepareTypesExists(index).setTypes(type).execute().actionGet().isExists()
125                 : false;
126     }
127 
128     /**
129      * 數據添加,正定ID
130      *
131      * @param mapObj 要增長的數據
132      * @param index      索引,相似數據庫
133      * @param type       類型,相似表
134      * @param id         數據ID
135      * @return
136      */
137     public static Map<String, Object> addData(Map<String, Object> mapObj, String index, String type, String id) {
138         IndexResponse response = client.prepareIndex(index, type, id).setSource(mapObj).get();
139         // response.getId():就是添加數據後ES爲這條數據所生成的id
140         // 須要返回添加數據是否成功
141         String status = response.status().toString();
142         // 添加數據後所返回的狀態(若是成功就是code:200-->OK)
143         // eq:sacii --> 小寫字母和大寫字母不同
144         // status:-->OK
145         // ok
146         if("OK".equals(status.toUpperCase())||"CREATED".equals(status.toUpperCase())) {
147             resultMap.put("code", StatusEnum.OPRATION_SUCCESS.getCode());
148             resultMap.put("msg", StatusEnum.OPRATION_SUCCESS.getMsg());
149         } else {
150             resultMap.put("code", StatusEnum.OPRATION_FAILED.getCode());
151             resultMap.put("msg", StatusEnum.OPRATION_FAILED.getMsg());
152         }
153         return resultMap;
154     }
155 
156     /**
157      * 數據添加
158      *
159      * @param mapObj 要增長的數據
160      * @param index      索引,相似數據庫
161      * @param type       類型,相似表
162      * @return
163      */
164     public static Map<String, Object> addData(Map<String, Object> mapObj, String index, String type) {
165         return addData(mapObj,index, type, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
166     }
167 
168     /**
169     * @author 劉其佳
170     * @description
171      *      將對象轉化爲map類型
172     * @param * param *:object
173     * @date 2019/9/19
174     * @return java.util.Map<java.lang.String,java.lang.Object>
175     * @throws
176     */
177     public static Map<String, Object> objectTurnMap(Object object){
178         Map<String, Object> result = new HashMap<String, Object>();
179         //得到類的屬性名  數組
180         Field[] fields = object.getClass().getDeclaredFields();
181         try {
182             for (Field field : fields) {
183                 field.setAccessible(true);
184                 String name = new String(field.getName());
185                 result.put(name, field.get(object));
186             }
187         }catch (Exception e){
188             e.printStackTrace();
189         }
190         return result;
191     }
192 
193     /**
194      * 經過ID刪除數據
195      *
196      * @param index 索引,相似數據庫
197      * @param type  類型,相似表
198      * @param id    數據ID
199      */
200     public static Map<String, Object> deleteDataById(String index, String type, String id) {
201 
202         DeleteResponse response = client.prepareDelete(index, type, id).execute().actionGet();
203         if("OK".equals(response.status().toString().toUpperCase())) {
204             resultMap.put("code", StatusEnum.OPRATION_SUCCESS.getCode());
205             resultMap.put("msg", StatusEnum.OPRATION_SUCCESS.getMsg());
206         } else {
207             resultMap.put("code", StatusEnum.OPRATION_FAILED.getCode());
208             resultMap.put("msg", StatusEnum.OPRATION_FAILED.getMsg());
209         }
210         return resultMap;
211 
212     }
213 
214     /**
215      * 經過ID 更新數據
216      *
217      * @param mapObj 要增長的數據
218      * @param index      索引,相似數據庫
219      * @param type       類型,相似表
220      * @param id         數據ID
221      * @return
222      */
223     public static Map<String, Object> updateDataById(Map<String, Object> mapObj, String index, String type, String id) {
224 
225         UpdateRequest updateRequest = new UpdateRequest();
226 
227         updateRequest.index(index).type(type).id(id).doc(mapObj);
228 
229         ActionFuture<UpdateResponse> update = client.update(updateRequest);
230 
231         if("OK".equals(update.actionGet().status().toString().toUpperCase())) {
232             resultMap.put("code", StatusEnum.OPRATION_SUCCESS.getCode());
233             resultMap.put("msg", StatusEnum.OPRATION_SUCCESS.getMsg());
234         } else {
235             resultMap.put("code", StatusEnum.OPRATION_FAILED.getCode());
236             resultMap.put("msg", StatusEnum.OPRATION_FAILED.getMsg());
237         }
238         return resultMap;
239     }
240 
241     /**
242      * 經過ID獲取數據
243      *
244      * @param index  索引,相似數據庫
245      * @param type   類型,相似表
246      * @param id     數據ID
247      * @param fields 須要顯示的字段,逗號分隔(缺省爲所有字段)
248      * @return
249      */
250     public static Map<String, Object> searchDataById(String index, String type, String id, String fields) {
251 
252         GetRequestBuilder getRequestBuilder = client.prepareGet(index, type, id);
253 
254         if (StringUtils.isNotEmpty(fields)) {
255             getRequestBuilder.setFetchSource(fields.split(","), null);
256         }
257 
258         GetResponse getResponse = getRequestBuilder.execute().actionGet();
259 
260         return getResponse.getSource();
261     }
262 
263     /**
264      * 使用分詞查詢
265      *
266      * @param index          索引名稱
267      * @param type           類型名稱,可傳入多個type逗號分隔
268      * @param query          查詢條件
269      * @param size           文檔大小限制
270      * @param fields         須要顯示的字段,逗號分隔(缺省爲所有字段)
271      * @param sortField      排序字段
272      * @param highlightField 高亮字段
273      * @return
274      */
275     public static List<Map<String, Object>> searchListData(
276             String index, String type, QueryBuilder query, Integer size,
277             String fields, String sortField, String highlightField) {
278 
279         SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
280         if (StringUtils.isNotEmpty(type)) {
281             searchRequestBuilder.setTypes(type.split(","));
282         }
283 
284         if (StringUtils.isNotEmpty(highlightField)) {
285             HighlightBuilder highlightBuilder = new HighlightBuilder();
286             // 設置高亮字段
287             highlightBuilder.field(highlightField);
288             searchRequestBuilder.highlighter(highlightBuilder);
289         }
290 
291         searchRequestBuilder.setQuery(query);
292 
293         if (StringUtils.isNotEmpty(fields)) {
294             searchRequestBuilder.setFetchSource(fields.split(","), null);
295         }
296         searchRequestBuilder.setFetchSource(true);
297 
298         if (StringUtils.isNotEmpty(sortField)) {
299             searchRequestBuilder.addSort(sortField, SortOrder.DESC);
300         }
301 
302         if (size != null && size > 0) {
303             searchRequestBuilder.setSize(size);
304         }
305 
306         //打印的內容 能夠在 Elasticsearch head 和 Kibana  上執行查詢
307 
308         SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
309 
310         long totalHits = searchResponse.getHits().totalHits;
311         long length = searchResponse.getHits().getHits().length;
312 
313         if (searchResponse.status().getStatus() == 200) {
314             // 解析對象
315             return setSearchResponse(searchResponse, highlightField);
316         }
317         return null;
318 
319     }
320 
321 
322     /**
323      * 高亮結果集 特殊處理
324      *
325      * @param searchResponse
326      * @param highlightField
327      */
328     private static List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {
329         List<Map<String, Object>> sourceList = new ArrayList<Map<String, Object>>();
330         StringBuffer stringBuffer = new StringBuffer();
331 
332         for (SearchHit searchHit : searchResponse.getHits().getHits()) {
333             searchHit.getSourceAsMap().put("id", searchHit.getId());
334 
335             if (StringUtils.isNotEmpty(highlightField)) {
336 
337                 System.out.println("遍歷 高亮結果集,覆蓋 正常結果集" + searchHit.getSourceAsMap());
338                 Text[] text = searchHit.getHighlightFields().get(highlightField).getFragments();
339 
340                 if (text != null) {
341                     for (Text str : text) {
342                         stringBuffer.append(str.string());
343                     }
344                     //遍歷 高亮結果集,覆蓋 正常結果集
345                     searchHit.getSourceAsMap().put(highlightField, stringBuffer.toString());
346                 }
347             }
348             sourceList.add(searchHit.getSourceAsMap());
349         }
350         return sourceList;
351     }
352 }

 

注意:上述代碼中有幾處標紅的地方:

  (1)工具類中有兩個添加數據的方法,緣由是:第一個添加方法在添加數據的時候指定ID

                        第二個添加方法在添加數據的時候隨機生成ID(即沒有指定ID)

      其實添加原理都是同樣,第二個添加方法原本就是調用了第一個的添加方法進行添加

  (2)在第一個添加數據的方法中,標紅的地方,原本只是進行了判斷status是否爲OK,

      但我後來又加上了一個判斷是否爲CREATED,

       緣由是:若是隻是添加一條數據的狀況下,添加成功的返回結果就是OK,可是我從數據庫中查出多個數據並添加進ES中,返回結果是CREATED

       即可以添加成功,可是返回結果不是OK,是CREATED

 

五、其次咱們要注意的是service層的方法:

  1 package com.aaa.liu.es.service;
  2 
  3 import com.aaa.liu.es.mapper.UserMapper;
  4 import com.aaa.liu.es.model.User;
  5 import com.aaa.liu.es.utils.ESUtil;
  6 import org.elasticsearch.index.query.*;
  7 import org.springframework.beans.factory.annotation.Autowired;
  8 import org.springframework.stereotype.Service;
  9 import org.springframework.web.bind.annotation.RequestMapping;
 10 
 11 import java.util.HashMap;
 12 import java.util.Iterator;
 13 import java.util.List;
 14 import java.util.Map;
 15 
 16 /**
 17  * @Author 劉其佳
 18  * @DateTime 2019/9/18 20:44
 19  * @Project_Name SpringBootEs
 20  */
 21 
 22 @Service
 23 public class SearchService {
 24 
 25     @Autowired
 26     private UserMapper userMapper;
 27 
 28     public static Map<String,Object> resultMap = new HashMap<String,Object>();
 29 
 30     /**
 31     * @author 劉其佳
 32     * @description
 33      *      建立index
 34     * @param * param *:index
 35     * @date 2019/9/18
 36     * @return java.util.Map<java.lang.String,java.lang.Object>
 37     * @throws
 38     */
 39     public Map<String,Object> createIndex(String index){
 40         return ESUtil.createIndex(index);
 41     }
 42 
 43     /**
 44     * @author 劉其佳
 45     * @description
 46      *      刪除index
 47     * @param * param *:index
 48     * @date 2019/9/18
 49     * @return java.util.Map<java.lang.String,java.lang.Object>
 50     * @throws
 51     */
 52     public Map<String,Object> deleteIndex(String index){
 53         return ESUtil.deleteIndex(index);
 54     }
 55 
 56     /**
 57     * @author 劉其佳
 58     * @description
 59      *      向ES的索引庫添加一條數據
 60      *          java.lang.IllegalArgumentException: The number of object passed must be even but was [1]:
 61      *          參數不合法異常
 62      *          在ES的6.x版本或者以上,廢棄掉了JSON對象傳遞數據,只能用Map傳遞
 63     * @param * param *:
 64     * @date 2019/9/18
 65     * @return java.util.Map<java.lang.String,java.lang.Object>
 66     * @throws
 67     */
 68     public Map<String,Object> addData(){
 69         // ES中不能再使用實體類,只能經過JSONObject對象進行傳遞數據來代替實體類
 70        /* JSONObject jsonObject = new JSONObject();
 71         jsonObject.put("id", 20L);
 72         jsonObject.put("username", "lisi");
 73         jsonObject.put("password", "123456");
 74         jsonObject.put("age", 30);*/
 75         Map<String,Object> dataMap=new HashMap<String, Object>();
 76         dataMap.put("id",21L);
 77         dataMap.put("username","饕餮");
 78         dataMap.put("password","123456");
 79         dataMap.put("age","20");
 80         return ESUtil.addData(dataMap,"test_index3","test_type3","10102");
 81     }
 82 
 83     /**
 84     * @author 劉其佳
 85     * @description
 86      *      從數據庫中查詢數據
 87      *          若是查到了就存入es中,
 88      *          若是沒有查到就返回null;
 89     * @param * param *:username
 90     * @date 2019/9/19
 91     * @return java.util.Map<java.lang.String,java.lang.Object>
 92     * @throws
 93     */
 94     public Map<String, Object> addDataBySql(String username){
 95         User user = userMapper.selectByUserName(username);
 96         if(user!=null){
 97             Map<String, Object> dataMap=new HashMap<String, Object>();
 98             dataMap.put("id",user.getId());
 99             dataMap.put("username",user.getUsername());
100             dataMap.put("password",user.getPassword());
101             dataMap.put("age",user.getAge());
102             return  ESUtil.addData(dataMap,"test_index2","test_type2","10103");
103         }else{
104             resultMap.put("result","未查詢到數據");
105             return resultMap;
106         }
107     }
108 
109     /**
110     * @author 劉其佳
111     * @description
112      *      從數據庫中查詢全部數據,並放入到ES中
113      *          其中用到了工具類中的對象轉Map方法
114     * @param * param *:index
115     * @date 2019/9/19
116     * @return java.util.Map<java.lang.String,java.lang.Object>
117     * @throws
118     */
119     public Map<String, Object> addAllData(String index){
120         List<User> userList = userMapper.selectAll();
121         if(userList.size()>0){
122             for (User user : userList) {
123                 Map<String , Object> mapObj=ESUtil.objectTurnMap(user);
124                 resultMap =  ESUtil.addData(mapObj,index,"test_type2");
125             }
126         }
127         return resultMap;
128     }
129 
130     /**
131     * @author 劉其佳
132     * @description
133      *      刪除數據
134     * @param * param *:index
135     * param *:type
136     * param *:id
137     * @date 2019/9/19
138     * @return java.util.Map<java.lang.String,java.lang.Object>
139     * @throws
140     */
141     public Map<String, Object> deleteDataById(String id){
142         return ESUtil.deleteDataById("test_index2", "test_type2", id);
143     }
144 
145     /**
146     * @author 劉其佳
147     * @description
148      *      經過id進行查詢數據
149      *      (id:是ES給這一條數據所上的索引)
150      *      searchDataById:一共須要傳遞四個參數
151      *          index,type,id,fields
152      *          fields:傳遞所要查詢的字段(username,age)
153      *          若是須要查詢全部的字段直接傳null
154     * @param * param *:id
155     * @date 2019/9/18
156     * @return java.util.Map<java.lang.String,java.lang.Object>
157     * @throws
158     */
159     public Map<String,Object> selectOneById(String id){
160         return ESUtil.searchDataById("test_index2","test_type2",id,null);
161     }
162 
163     /**
164     * @author 劉其佳
165     * @description
166      *      查詢全部的數據
167      *          index
168      *          type
169      *          QueryBuilder:定義了查詢條件(是所有查詢 仍是模糊查詢 仍是分頁查詢。。。。)
170      *          size:所要查詢出的條數
171      *          field:所查詢的字段(若是查詢全部就直接寫null)
172      *          sortField:id,age...(根據字段進行排序,若是不須要設置則傳null)
173      *          highlightField:把搜索關鍵字進行高亮顯示(若是不須要則傳null)
174     * @param * param *:
175     * @date 2019/9/18
176     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
177     * @throws
178     */
179     public List<Map<String,Object>> selectAll(){
180         //一、建立QueryBuilder對象(BoolQueryBuilder是Builder的實現類)
181         BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery();
182         //二、建立所要搜索到額條件(查詢全部數據)
183         MatchAllQueryBuilder matchAllQueryBuilder=QueryBuilders.matchAllQuery();
184         //三、把搜索的條件放入到BoolQueryBuilder中
185         BoolQueryBuilder must = boolQueryBuilder.must(matchAllQueryBuilder);
186         //四、返回
187         return ESUtil.searchListData("test_index2","test_type2",must,100,null,null,null);
188     }
189 
190     /**
191     * @author 劉其佳
192     * @description
193      *      模糊查詢
194      *      在ES中默認若是單詞之間沒有鏈接符就會被當成一個單詞
195      *      例如zhangsan  就會被默認爲一個詞
196      *      若是須要進行模糊匹配 在ES中必需要要使用連字符(_ - =.....)
197      *      由於ES的分詞器作的不夠好,尤爲是中文(必需要整合本身的分詞器(IK),若是作得是職業搜索(用的最多的是搜狗)) 198      *      IK分詞器集成很簡單,不須要任何配置
199      *          IK分詞器:
200      *              在ES的服務器,在plugins目錄中建立IK文件夾(必定要大寫)
201      *              把IK分詞器解壓在IK目錄中
202      *              再次對ES文件夾進行受權
203     * @param * param *:
204     * @date 2019/9/19
205     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
206     * @throws
207     */
208     public List<Map<String,Object>> selectLikeAll(String username){
209         //一、建立QueryBuilder對象
210         BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
211         //二、建立查詢條件
212         //  matchPhraseQuery有兩個參數:
213             //name:字段名字
214             //text:所須要模糊匹配的值(也就是SQL語句中like後面所匹配的值)
215 //        MatchPhraseQueryBuilder matchPhraseQueryBuilder=QueryBuilders.matchPhraseQuery("username","zhang");
216         MatchPhraseQueryBuilder matchPhraseQueryBuilder=QueryBuilders.matchPhraseQuery("username",username);
217         //三、把查詢條件放到BoolQueryBuilder對象中
218         BoolQueryBuilder must=boolQueryBuilder.must(matchPhraseQueryBuilder);
219         return ESUtil.searchListData("test_index2","test_type2",must,10,null,null,"username");
220     }
221 
222 //    public void testQueryByStr(){
223 //        try {
224 //            String searchStr = "陳夏天u馬立,@45";
225 //            QueryStringQueryBuilder builder = new QueryStringQueryBuilder(searchStr);
226 //
227 //            //  重點是下面這行代碼
228 //            builder.analyzer("myanalyzer").field("username").field("password").field("age");
229 //            Iterable<User> search = userRepository.search(builder);
230 //            Iterator<User> iterator = search.iterator();
231 //            while (iterator.hasNext()){
232 //                System.out.println("---> 匹配數據: "+iterator.next());
233 //            }
234 //        }catch (Exception e){
235 //            System.out.println("---> 異常信息 "+e);
236 //        }
237 //    }
238 }

 

注意:(1)在往ES中添加數據時,咱們之前使用JSON格式進行傳輸,但在ES6.x版本以上 廢棄了JSONObject,如今須要使用Map

      (2)在service層中定義的模糊查詢的方法(此處使用的是ES自帶的分詞器,極其不合格,建議使用IK分詞器或者搜狗;

                    不過使IK分詞的話須要注意的是IK分詞器的版本要與ES版本一致(大版本和小版本上都要一致));

      ES自帶的分詞器:若是有一個字段是zhangsan,咱們使用關鍵字zhang進行搜索,按理說咱們應該可以搜索到的,

      但結果顯示沒有搜索到,緣由是ES自帶的分詞器將zhangsan當作了一個詞,

      若是想要達到咱們想要的分詞效果,咱們須要帶上連字符,例如:zhang-san、zhang_san等

 

六、下面放上個人controller:

  1 package com.aaa.liu.es.controller;
  2 
  3 import com.aaa.liu.es.service.SearchService;
  4 import org.springframework.beans.factory.annotation.Autowired;
  5 import org.springframework.web.bind.annotation.RequestMapping;
  6 import org.springframework.web.bind.annotation.RestController;
  7 
  8 import java.util.List;
  9 import java.util.Map;
 10 
 11 /**
 12  * @Author 劉其佳
 13  * @DateTime 2019/9/18 20:41
 14  * @Project_Name SpringBootEs
 15  */
 16 @RestController
 17 public class SearchController {
 18 
 19     @Autowired
 20      private SearchService searchService;
 21 
 22     /**
 23     * @author 劉其佳
 24     * @description
 25      *         建立索引
 26     * @param * param *:index
 27     * @date 2019/9/18
 28     * @return java.util.Map<java.lang.String,java.lang.Object>
 29     * @throws
 30     */
 31     @RequestMapping("/createIndex")
 32      public Map<String,Object> createIndex(String index){
 33          return searchService.createIndex(index);
 34      }
 35 
 36      /**
 37      * @author 劉其佳
 38      * @description
 39       *         刪除索引
 40      * @param * param *:index
 41      * @date 2019/9/18
 42      * @return java.util.Map<java.lang.String,java.lang.Object>
 43      * @throws
 44      */
 45      @RequestMapping("/deleteIndex")
 46      public Map<String,Object> deleteIndex(String index){
 47         return searchService.deleteIndex(index);
 48      }
 49 
 50 
 51      /**
 52      * @author 劉其佳
 53      * @description
 54       *     向ES的索引庫中添加一條數據
 55      * @param * param *:
 56      * @date 2019/9/18
 57      * @return java.util.Map<java.lang.String,java.lang.Object>
 58      * @throws
 59      */
 60      @RequestMapping("/addData")
 61      public Map<String,Object> addData(){
 62          return searchService.addData();
 63      }
 64 
 65      /**
 66      * @author 劉其佳
 67      * @description
 68       *     從數據庫中查詢數據並存入到es中
 69      * @param * param *:username
 70      * @date 2019/9/19
 71      * @return java.util.Map<java.lang.String,java.lang.Object>
 72      * @throws
 73      */
 74      @RequestMapping("/addDataBySql")
 75      public Map<String, Object> addDataBySql(String username){
 76          return searchService.addDataBySql(username);
 77      }
 78 
 79      /**
 80      * @author 劉其佳
 81      * @description
 82       *         從數據庫中查詢全部數據並放入到ES中
 83      * @param * param *:index
 84      * @date 2019/9/19
 85      * @return java.util.Map<java.lang.String,java.lang.Object>
 86      * @throws
 87      */
 88      @RequestMapping("/addAllData")
 89      public Map<String ,Object> addAllData(String index){
 90          return searchService.addAllData(index);
 91      }
 92      /**
 93      * @author 劉其佳
 94      * @description
 95       *         根據Id刪除數據
 96      * @param * param *:id
 97      * @date 2019/9/19
 98      * @return java.util.Map<java.lang.String,java.lang.Object>
 99      * @throws
100      */
101      @RequestMapping("/deleteDataById")
102      public Map<String, Object> deleteDataById(String id){
103          return searchService.deleteDataById(id);
104      }
105      /**
106      * @author 劉其佳
107      * @description
108       *         經過某條數據的id進行查詢數據
109      * @param * param *:id
110      * @date 2019/9/18
111      * @return java.util.Map<java.lang.String,java.lang.Object>
112      * @throws
113      */
114      @RequestMapping("/selectById")
115      public Map<String,Object> selectOneById(String id){
116          return searchService.selectOneById(id);
117      }
118 
119      /**
120      * @author 劉其佳
121      * @description
122       *     查詢某index、某type下的全部數據
123      * @param * param *:
124      * @date 2019/9/18
125      * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
126      * @throws
127      */
128      @RequestMapping("/selectAll")
129      public List<Map<String,Object>> selectAll(){
130          return searchService.selectAll();
131      }
132 
133      /**
134      * @author 劉其佳
135      * @description
136       *     模糊查詢
137      * @param * param *:
138      * @date 2019/9/19
139      * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
140      * @throws
141      */
142      @RequestMapping("/selectLikeAll")
143      public List<Map<String,Object>> selectLikeAll(String username){
144          return searchService.selectLikeAll(username);
145      }
146 }

 

七、將枚舉類放上來:

 1 package com.aaa.liu.es.status;
 2 
 3 /** 5  * @Author Seven Lee
 6  * @Date Create in 2019/9/18 16:14
 7  * @Description
 8  **/
 9 public enum StatusEnum {
10 
11     OPRATION_SUCCESS("200", "操做成功"),
12     OPRATION_FAILED("401", "操做失敗"),
13     EXIST("101", "數據存在"),
14     NOT_EXIST("402", "數據不存在");
15 
16     StatusEnum(String code, String msg) {
17         this.code = code;
18         this.msg = msg;
19     }
20 
21     private String code;
22     private String msg;
23 
24     public String getCode() {
25         return code;
26     }
27 
28     public void setCode(String code) {
29         this.code = code;
30     }
31 
32     public String getMsg() {
33         return msg;
34     }
35 
36     public void setMsg(String msg) {
37         this.msg = msg;
38     }
39 }
相關文章
相關標籤/搜索