一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

2021-04-27 11:47虛無境 Java教程

簡單說,ElasticSearch(簡稱 ES)是搜索引擎,是結構化數據的分布式搜索引擎。下面這篇文章主要給大家介紹了關于Spring Boot整合ElasticSearch實現多版本兼容的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧

前言

上一篇學習springboot中,整合了mybatis、druid和pagehelper并實現了多數據源的操作。本篇主要是介紹和使用目前最火的搜索引擎elastisearch,并和springboot進行結合使用。

elasticsearch介紹

elasticsearch是一個基于lucene的搜索服務器,其實就是對lucene進行封裝,提供了 rest api 的操作接口 elasticsearch作為一個高度可拓展的開源全文搜索和分析引擎,可用于快速地對大數據進行存儲,搜索和分析。

elasticsearch主要特點:分布式、高可用、異步寫入、多api、面向文檔 。

elasticsearch核心概念:近實時,集群,節點(保存數據),索引,分片(將索引分片),副本(分片可設置多個副本) 。它可以快速地儲存、搜索和分析海量數據。

elasticsearch使用案例:維基百科、stack overflow、github 等等。

springboot整合elasticsearch

在使用springboot整合elasticsearch 之前,我們應該了解下它們之間對應版本的關系。

 

spring boot version (x) spring data elasticsearch version (y) elasticsearch version (z)
x <= 1.3.5 y <= 1.3.4 z <= 1.7.2*
x >= 1.4.x 2.0.0 <=y < 5.0.0** 2.0.0 <= z < 5.0.0**

 

這里我們使用的springboot的版本是1.5.9,elasticsearch的版本是2.3.5。

使用springboot整合elasticsearch,一般都是使用 springdata 進行封裝的,然后再dao層接口繼承elasticsearchrepository 類,該類實現了很多的方法,比如常用的crud方法。

springdata的使用

首先,在使用之前,先做好相關的準備。

maven的配置如下:

?
1
2
3
4
5
6
7
8
9
<dependency> <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-web</artifactid>
 <version>1.5.9.release</version>
 </dependency>
 <dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-data-elasticsearch</artifactid>
 <version>1.5.9.release</version>
 </dependency>

application.properties的配置

?
1
2
spring.data.elasticsearch.repositories.enabled = true
spring.data.elasticsearch.cluster-nodes =127.0.0.1\:9300

注: 9300 是 java 客戶端的端口。9200 是支持 restful http 的接口。

更多的配置:

spring.data.elasticsearch.cluster-name elasticsearch 集群名。(默認值: elasticsearch)
spring.data.elasticsearch.cluster-nodes 集群節點地址列表,用逗號分隔。如果沒有指定,就啟動一個客戶端節點。
spring.data.elasticsearch.propertie 用來配置客戶端的額外屬性。
spring.data.elasticsearch.repositories.enabled 開啟 elasticsearch 倉庫。(默認值:true。)

代碼編寫

實體類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@document(indexname = "userindex", type = "user")
public class user implements serializable{
 /**
 *
 */
 private static final long serialversionuid = 1l;
 /** 編號 */
 private long id;
 /** 姓名 */
 private string name;
 
 /** 年齡 */
 private integer age;
 
 /** 描述 */
 private string description;
 
 /** 創建時間 */
 private string createtm;
 // getter和setter 略

使用springdata的時候,它需要在實體類中設置indexname 和type ,如果和傳統型數據庫比較的話,就相當于庫和表。

需要注意的是indexname和type都必須是小寫!!!

dao層

?
1
2
public interface userdao extends elasticsearchrepository<user, long>{
}

dao層這里就比較簡單了,只需繼承elasticsearchrepository該類就行了。其中主要的方法就是 save、delete和search。其中save方法相當如insert和update,沒有就新增,有就覆蓋。delete方法主要就是刪除數據以及索引庫。至于search就是查詢了,包括一些常用的查詢,如分頁、權重之類的。

service層

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@service
public class userserviceimpl implements userservice {
 @autowired
 private userdao userdao;
 @override
 public boolean insert(user user) {
 boolean falg=false;
 try{
 userdao.save(user);
 falg=true;
 }catch(exception e){
 e.printstacktrace();
 }
 return falg;
 }
 
 @override
 public list<user> search(string searchcontent) {
 querystringquerybuilder builder = new querystringquerybuilder(searchcontent);
 system.out.println("查詢的語句:"+builder);
 iterable<user> searchresult = userdao.search(builder);
 iterator<user> iterator = searchresult.iterator();
 list<user> list=new arraylist<user>();
 while (iterator.hasnext()) {
 list.add(iterator.next());
 }
 return list;
 }
 
 
 
 @override
 public list<user> searchuser(integer pagenumber, integer pagesize,string searchcontent) {
 // 分頁參數
 pageable pageable = new pagerequest(pagenumber, pagesize);
 querystringquerybuilder builder = new querystringquerybuilder(searchcontent);
 searchquery searchquery = new nativesearchquerybuilder().withpageable(pageable).withquery(builder).build();
 system.out.println("查詢的語句:" + searchquery.getquery().tostring());
 page<user> searchpageresults = userdao.search(searchquery);
 return searchpageresults.getcontent();
 }
 
 
 @override
 public list<user> searchuserbyweight(string searchcontent) {
 // 根據權重進行查詢
 functionscorequerybuilder functionscorequerybuilder = querybuilders.functionscorequery()
 .add(querybuilders.boolquery().should(querybuilders.matchquery("name", searchcontent)),
  scorefunctionbuilders.weightfactorfunction(10))
 .add(querybuilders.boolquery().should(querybuilders.matchquery("description", searchcontent)),
  scorefunctionbuilders.weightfactorfunction(100)).setminscore(2);
 system.out.println("查詢的語句:" + functionscorequerybuilder.tostring());
 iterable<user> searchresult = userdao.search(functionscorequerybuilder);
 iterator<user> iterator = searchresult.iterator();
 list<user> list=new arraylist<user>();
 while (iterator.hasnext()) {
 list.add(iterator.next());
 }
 return list;
 }
}

這里我就簡單的寫了幾個方法,其中主要的方法是查詢。查詢包括全文搜索,分頁查詢和權重查詢。其中需要說明的是權重查詢這塊,權重的分值越高,查詢的結果也越靠前,如果沒有對其它的數據設置分值,它們默認的分值就是1,如果不想查詢這些語句,只需使用setminscore將其設為大于1即可。

代碼測試

調用接口進行添加數據

新增數據:

?
1
2
3
4
post http://localhost:8086/api/user
{"id":1,"name":"張三","age":20,"description":"張三是個java開發工程師","createtm":"2018-4-25 11:07:42"}
{"id":2,"name":"李四","age":24,"description":"李四是個測試工程師","createtm":"1980-2-15 19:01:32"}
{"id":3,"name":"王五","age":25,"description":"王五是個運維工程師","createtm":"2016-8-21 06:11:32"}

進行全文查詢

請求

?
1
http://localhost:8086/api/user?searchcontent=工程師

返回

?
1
2
3
[{"id":2,"name":"李四","age":14,"description":"李四是個測試工程師","createtm": "1980-2-15 19:01:32"},
{"id":1,"name":"張三","age":20,"description":"張三是個java開發工程師", "createtm": "2018-4-25 11:07:42"},
{"id":3,"name":"王五","age":25,"description":"王五是個運維工程師","createtm": "2016-8-21 06:11:32"}]

進行分頁查詢

請求

?
1
http://localhost:8086/api/user?pagenumber=0&pagesize=2&searchcontent=工程師

返回

?
1
[{"id":2,"name":"李四","age":14,"description":"李四是個測試工程師"},{"id":1,"name":"張三","age":20,"description":"張三是個java開發工程師"}]

進行權重查詢

請求

?
1
http://localhost:8086/api/user2?searchcontent=李四

返回

?
1
[{"id":2,"name":"李四","age":24,"description":"李四是個測試工程師","createtm":"1980-2-15 19:01:32"}]

權重查詢打印的語句:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
查詢的語句:{{
 "function_score" : {
 "functions" : [ {
 "filter" : {
 "bool" : {
 "should" : {
 "match" : {
 "name" : {
 "query" : "李四",
 "type" : "boolean"
 }
 }
 }
 }
 },
 "weight" : 10.0
 }, {
 "filter" : {
 "bool" : {
 "should" : {
 "match" : {
 "description" : {
 "query" : "李四",
 "type" : "boolean"
 }
 }
 }
 }
 },
 "weight" : 100.0
 } ],
 "min_score" : 2.0
 }
}

注:測試中,因為設置了setminscore最小權重分為2的,所以無關的數據是不會顯示出來的。如果想顯示的話,在代碼中去掉即可。

新增完數據之后,可以在瀏覽器輸入:http://localhost:9200/_plugin/head/

然后點擊基本查詢,便可以查看添加的數據。如果想用語句查詢,可以將程序中控制臺打印的查詢語句粘貼到查詢界面上進行查詢!

Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

注:這里的elasticsearch是我在windows上安裝的,并安裝了es插件head,具體安裝步驟在文章末尾。

除了springdata之外,其實還有其它的方法操作elasticsearch的。

比如使用原生elasticsearch的api,使用transportclient類實現。

或者使用由spring封裝,只需在service層,進行注入bean即可。

示例:

?
1
2
@autowired
 elasticsearchtemplate elasticsearchtemplate;

但是,上述方法中都有其局限性,也就是隨著elasticsearch的版本變更,相關的java api也在做不斷的調整,就是elasticsearch服務端版本進行更改之后,客戶端的代碼可能需要重新編寫。

因此介紹一個相當好用的第三方工具jestclient,它對elasticsearch進行封裝,填補了 elasticsearch httprest接口 客戶端的空白,它適用于elasticsearch2.x以上的版本,無需因為elasticsearch服務端版本更改而對代碼進行更改!

jestclient

首先在maven中添加如下依賴:

?
1
2
3
4
5
<dependency>
<groupid>io.searchbox</groupid>
<artifactid>jest</artifactid>
<version>5.3.3</version>
</dependency>

然后編寫相關的測試代碼。

代碼中的注釋應該很完整,所以這里就不再對代碼過多的講述了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import java.util.arraylist;
import java.util.list;
import org.elasticsearch.index.query.querybuilders;
import org.elasticsearch.search.builder.searchsourcebuilder;
import com.pancm.pojo.user;
import io.searchbox.client.jestclient;
import io.searchbox.client.jestclientfactory;
import io.searchbox.client.jestresult;
import io.searchbox.client.config.httpclientconfig;
import io.searchbox.core.bulk;
import io.searchbox.core.bulkresult;
import io.searchbox.core.delete;
import io.searchbox.core.documentresult;
import io.searchbox.core.index;
import io.searchbox.core.search;
import io.searchbox.indices.createindex;
import io.searchbox.indices.deleteindex;
import io.searchbox.indices.mapping.getmapping;
import io.searchbox.indices.mapping.putmapping;
 
public class jesttest {
 private static jestclient jestclient;
 private static string indexname = "userindex";
// private static string indexname = "userindex2";
 private static string typename = "user";
 private static string elasticips="http://192.169.2.98:9200";
// private static string elasticips="http://127.0.0.1:9200";
 
 
 public static void main(string[] args) throws exception {
 jestclient = getjestclient();
 insertbatch();
 serach1();
 serach2();
 serach3();
 jestclient.close();
 
 }
 
 private static jestclient getjestclient() {
 jestclientfactory factory = new jestclientfactory();
 factory.sethttpclientconfig(new httpclientconfig.builder(elasticips).conntimeout(60000).readtimeout(60000).multithreaded(true).build());
 return factory.getobject();
 }
 
 public static void insertbatch() {
 list<object> objs = new arraylist<object>();
 objs.add(new user(1l, "張三", 20, "張三是個java開發工程師","2018-4-25 11:07:42"));
 objs.add(new user(2l, "李四", 24, "李四是個測試工程師","1980-2-15 19:01:32"));
 objs.add(new user(3l, "王五", 25, "王五是個運維工程師","2016-8-21 06:11:32"));
 boolean result = false;
 try {
 result = insertbatch(jestclient,indexname, typename,objs);
 } catch (exception e) {
 e.printstacktrace();
 }
 system.out.println("批量新增:"+result);
 }
 
 
 /**
 * 全文搜索
 */
 public static void serach1() {
 string query ="工程師";
 try {
 searchsourcebuilder searchsourcebuilder = new searchsourcebuilder();
  searchsourcebuilder.query(querybuilders.querystringquery(query));
  //分頁設置
  searchsourcebuilder.from(0).size(2);
 system.out.println("全文搜索查詢語句:"+searchsourcebuilder.tostring());
 system.out.println("全文搜索返回結果:"+search(jestclient,indexname, typename, searchsourcebuilder.tostring()));
 } catch (exception e) {
 e.printstacktrace();
 }
 }
 
 /**
 * 精確搜索
 */
 public static void serach2() {
 try {
 searchsourcebuilder searchsourcebuilder = new searchsourcebuilder();
 searchsourcebuilder.query(querybuilders.termquery("age", 24));
 system.out.println("精確搜索查詢語句:"+searchsourcebuilder.tostring());
 system.out.println("精確搜索返回結果:"+search(jestclient,indexname, typename, searchsourcebuilder.tostring()));
 } catch (exception e) {
 e.printstacktrace();
 }
 }
 
 
 /**
 * 區間搜索
 */
 public static void serach3() {
 string createtm="createtm";
 string from="2016-8-21 06:11:32";
 string to="2018-8-21 06:11:32";
 
 try {
 searchsourcebuilder searchsourcebuilder = new searchsourcebuilder();
 searchsourcebuilder.query(querybuilders.rangequery(createtm).gte(from).lte(to));
 system.out.println("區間搜索語句:"+searchsourcebuilder.tostring());
 system.out.println("區間搜索返回結果:"+search(jestclient,indexname, typename, searchsourcebuilder.tostring()));
 } catch (exception e) {
 e.printstacktrace();
 }
 }
 
 
 /**
 * 創建索引
 * @param indexname
 * @return
 * @throws exception
 */
 public boolean createindex(jestclient jestclient,string indexname) throws exception {
 jestresult jr = jestclient.execute(new createindex.builder(indexname).build());
 return jr.issucceeded();
 }
 
 /**
 * 新增數據
 * @param indexname
 * @param typename
 * @param source
 * @return
 * @throws exception
 */
 public boolean insert(jestclient jestclient,string indexname, string typename, string source) throws exception {
 putmapping putmapping = new putmapping.builder(indexname, typename, source).build();
 jestresult jr = jestclient.execute(putmapping);
 return jr.issucceeded();
 }
 
 
 /**
 * 查詢數據
 * @param indexname
 * @param typename
 * @return
 * @throws exception
 */
 public static string getindexmapping(jestclient jestclient,string indexname, string typename) throws exception {
 getmapping getmapping = new getmapping.builder().addindex(indexname).addtype(typename).build();
 jestresult jr =jestclient.execute(getmapping);
 return jr.getjsonstring();
 }
 
 
 
 /**
 * 批量新增數據
 * @param indexname
 * @param typename
 * @param objs
 * @return
 * @throws exception
 */
 public static boolean insertbatch(jestclient jestclient,string indexname, string typename, list<object> objs) throws exception {
 bulk.builder bulk = new bulk.builder().defaultindex(indexname).defaulttype(typename);
 for (object obj : objs) {
 index index = new index.builder(obj).build();
  bulk.addaction(index);
 }
 bulkresult br = jestclient.execute(bulk.build());
 return br.issucceeded();
 }
 
 /**
 * 全文搜索
 * @param indexname
 * @param typename
 * @param query
 * @return
 * @throws exception
 */
 public static string search(jestclient jestclient,string indexname, string typename, string query) throws exception {
 search search = new search.builder(query)
 .addindex(indexname)
 .addtype(typename)
 .build();
 jestresult jr = jestclient.execute(search);
// system.out.println("--"+jr.getjsonstring());
// system.out.println("--"+jr.getsourceasobject(user.class));
 return jr.getsourceasstring();
 }
 
 
 
 
 
 /**
 * 刪除索引
 * @param indexname
 * @return
 * @throws exception
 */
 public boolean delete(jestclient jestclient,string indexname) throws exception {
 jestresult jr = jestclient.execute(new deleteindex.builder(indexname).build());
 return jr.issucceeded();
 }
 
 /**
 * 刪除數據
 * @param indexname
 * @param typename
 * @param id
 * @return
 * @throws exception
 */
 public boolean delete(jestclient jestclient,string indexname, string typename, string id) throws exception {
 documentresult dr = jestclient.execute(new delete.builder(id).index(indexname).type(typename).build());
 return dr.issucceeded();
 }

注:測試之前先說明下,本地windows系統安裝的是elasticsearch版本是2.3.5,linux服務器上安裝的elasticsearch版本是6.2。

測試結果

全文搜索

?
1
2
3
4
5
6
7
8
9
10
11
全文搜索查詢語句:{
 "from" : 0,
 "size" : 2,
 "query" : {
 "query_string" : {
 "query" : "工程師"
 }
 }
}
 
全文搜索返回結果:{"id":1,"name":"張三","age":20,"description":"張三是個java開發工程師","createtm":"2018-4-25 11:07:42"},{"id":2,"name":"李四","age":24,"description":"李四是個測試工程師","createtm":"1980-2-15 19:01:32"}

匹配搜索

?
1
2
3
4
5
6
7
8
9
精確搜索查詢語句:{
 "query" : {
 "term" : {
 "age" : 24
 }
 }
}
 
精確搜索返回結果:{"id":2,"name":"李四","age":24,"description":"李四是個測試工程師","createtm":"1980-2-15 19:01:32"}

時間區間搜索

?
1
2
3
4
5
6
7
8
9
10
11
12
13
區間搜索語句:{
 "query" : {
 "range" : {
 "createtm" : {
 "from" : "2016-8-21 06:11:32",
 "to" : "2018-8-21 06:11:32",
 "include_lower" : true,
 "include_upper" : true
 }
 }
 }
}
區間搜索返回結果:{"id":1,"name":"張三","age":20,"description":"張三是個java開發工程師","createtm":"2018-4-25 11:07:42"}

新增完數據之后,我們可以上linux的 kibana中進行相關的查詢,查詢結果如下:

Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

注:kibana 是屬于elk中一個開源軟件。kibana可以為 logstash 和 elasticsearch 提供的日志分析友好的 web 界面,可以幫助匯總、分析和搜索重要數據日志。

上述代碼中測試返回的結果符合我們的預期。其中關于jestclient只是用到了很少的一部分,更多的使用可以查看jestclient的官方文檔。

windows安裝elasticsearch

1,文件準備

下載地址:https://www.elastic.co/downloads

選擇elasticsearch相關版本, 然后選擇后綴名為zip文件進行下載,下載之后進行解壓。

2,啟動elasticsearch

進入bin目錄下,運行 elasticsearch.bat

然后在瀏覽上輸入: localhost:9200

成功顯示一下界面表示成功!

Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

3,安裝es插件

web管理界面head 安裝

進入bin目錄下,打開cmd,進入dos界面

輸入:plugin install mobz/elasticsearch-head

進行下載

成功下載之后,在瀏覽器輸入:http://localhost:9200/_plugin/head/

若顯示一下界面,則安裝成功!

Spring Boot整合ElasticSearch實現多版本兼容的方法詳解

4,注冊服務

進入bin目錄下,打開cmd,進入dos界面

依次輸入:

?
1
2
service.bat install
service.bat start

成功之后,再輸入

?
1
services.msc

跳轉到service服務界面,可以直接查看es的運行狀態!

其它

elasticsearch官網api地址:

https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html

jestclientgithub地址:

https://github.com/searchbox-io/jest

項目我放到github上面去了。

https://github.com/xuwujing/springboot

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://www.cnblogs.com/xuwujing/p/8998168.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 韩国三级在线观看 完整版 韩国三级视频网站 | 亚洲精品αv一区二区三区 亚洲精品91大神在线观看 | 星空无限传媒xk8129 | 7mav视频| 朝鲜美女免费一级毛片 | 深夜福利一区 | 亚洲乱亚洲乱妇41p 亚洲乱码一区二区三区国产精品 | 国产精品久久一区 | 日本视频中文字幕 | 亚洲美色综合天天久久综合精品 | 美女的让男生桶 | 好大好深受不了了快进来 | blacked亚裔videoshd | 韩国成人毛片aaa黄 含羞草国产亚洲精品岁国产精品 | 色狠狠色狠狠综合天天 | 草莓视频看污 | 亚洲黄色成人 | 扒开黑女人p大荫蒂老女人 扒开大腿狠狠挺进视频 | 69堂最新地域网名 | 青青久久久国产线免观 | 男人晚上适合偷偷看的污污 | 国产在线拍 | 国产精品原创永久在线观看 | 成人网视频免费播放 | 99久久国产亚洲综合精品 | 亚洲欧美日韩综合在线播放 | 密臀tv| a级免费在线观看 | 欧美日韩视频一区三区二区 | 青草视频在线观看免费网站 | 羞羞视频麻豆 | 日本福利网 | 日韩精品成人在线 | 欧美a一片xxxx片与善交 | 1377大但人文艺术包子铺 | 国产精品亚欧美一区二区三区 | 国产成人精品999在线 | 2022国产麻豆剧传媒剧情 | 草莓绿巨人香蕉茄子芭乐 | 88av免费观看 | 9999热视频 |