03.04 一篇就懂 Elasticsearch

一篇就懂 Elasticsearch | 原力計劃

作者 | mr_xinchen

來源 | CSDN博客

出品 | CSDN(ID:CSDNnews)

一篇就懂 Elasticsearch | 原力计划

Elasticsearch介紹

Elasticsearch是一款基於Lucene的分佈式全文檢索服務器,讓我們看一下百度文庫給出的解釋。

用途:做搜索功能使用案例:GitHub、維基百科、等等Solr對比:

  • 實時性ES高於Solr

  • Solr傳統搜索性能高於ES

一篇就懂 Elasticsearch | 原力计划

Elasticsearch安裝

注意:安裝必須在java1.8版本以上Windows環境

  1. 去官網下載獲得壓縮包一個,版本6.2.4

  2. 解壓縮進入目錄找到bin文件夾

  3. 雙擊運行bin文件夾中elasticsearch.bat腳本

  4. 在瀏覽器輸入http://localhost:9200/

安裝成功瀏覽器顯示

一篇就懂 Elasticsearch | 原力计划

Linux環境

1. 安裝和配置

我們將在linux下安裝Elasticsearch,使用版本6.2.4

2. 新建一個用戶

出於安全考慮,elasticsearch默認不允許以root賬號運行。

創建用戶:

1useradd 用戶名

設置密碼:

1passwd 用戶名

切換用戶:

1su 用戶名

3. 上傳安裝包,並解壓

我們將安裝包上傳到:/home/用戶名目錄

解壓縮:

1tar -zxvf elasticsearch-6.2.4.tar.gz

我們把目錄重命名:

1mv elasticsearch-6.2.4/ elasticsearch

進入,查看目錄結構:

1ls -l /home/用戶名/elasticsearch

4. 修改配置

我們進入config目錄:cd config

需要修改的配置文件有兩個:

jvm.options

Elasticsearch基於Lucene的,而Lucene底層是java實現,因此我們需要配置jvm參數。

1vim jvm.options

默認配置如下:

1-Xms1g
2-Xmx1g

內存佔用太多了,我們調小一些:

1-Xms512m
2-Xmx512m

elasticsearch.yml

1vim elasticsearch.yml

  • 修改數據和日誌目錄:

1path.data: /home/用戶名/elasticsearch/data # 數據目錄位置
2path.logs: /home/用戶名/elasticsearch/logs # 日誌目錄位置

我們把data和logs目錄修改指向了elasticsearch的安裝目錄。但是這兩個目錄並不存在,因此我們需要創建出來。

進入elasticsearch的根目錄,然後創建:

1mkdir data
2mkdir logs
  • 修改綁定的ip:

1network.host: 0.0.0.0 # 綁定到0.0.0.0,允許任何ip來訪問

默認只允許本機訪問,修改為0.0.0.0後則可以遠程訪問

目前我們是做的單機安裝,如果要做集群,只需要在這個配置文件中添加其它節點信息即可。

elasticsearch.yml的其它可配置信息:

一篇就懂 Elasticsearch | 原力计划

5. 運行

進入elasticsearch/bin目錄,可以看到下面的執行文件:

然後輸入命令:

1./elasticsearch

發現報錯了,啟動失敗:

  • 錯誤1:內核過低

我們使用的是centos6,其linux內核版本為2.6。而Elasticsearch的插件要求至少3.5以上版本。不過沒關係,我們禁用這個插件即可。

修改elasticsearch.yml文件,在最下面添加如下配置:

1bootstrap.system_call_filter: false

然後重啟

  • 錯誤2:文件權限不足

再次啟動,又出錯了:

1[1]: max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

我們用的是普通用戶,而不是root,所以文件權限不足。

首先用root用戶登錄。

然後修改配置文件:

1vim /etc/security/limits.conf

添加下面的內容:

1* soft nofile 65536
2
3* hard nofile 131072
4
5* soft nproc 4096
6
7* hard nproc 4096
  • 錯誤3:線程數不夠

剛才報錯中,還有一行:

1[1]: max number of threads [1024] for user [leyou] is too low, increase to at least [4096]

這是線程數不夠。

繼續修改配置:

1vim /etc/security/limits.d/90-nproc.conf 

修改下面的內容:

1* soft nproc 1024

改為:

1* soft nproc 4096

  • 錯誤4:進程虛擬內存

1[3]: max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]

vm.max_map_count:限制一個進程可以擁有的VMA(虛擬內存區域)的數量,繼續修改配置文件, :

1vim /etc/sysctl.conf

添加下面內容:

1vm.max_map_count=655360

然後執行命令:

1sysctl -p

6. 重啟終端窗口

所有錯誤修改完畢,一定要重啟你的 Xshell終端,否則配置無效。

7. 啟動

進入elasticsearch/bin目錄,然後輸入命令:

1./elasticsearch

可以看到綁定了兩個端口:

  • 9300:集群節點間通訊接口

  • 9200:客戶端訪問接口

我們在瀏覽器中訪問:http://127.0.0.1:9200

一篇就懂 Elasticsearch | 原力计划

Elasticsearch理論知識

看過我上篇Lucene的文章,大家知道我把Lucene和傳統數據庫對比,其實他們很多相同之處,接下來我們拿Elasticsearch和Mysql進行比較。

1Mysql -> database -> table -> rows -> columns
2
3Elasticsearch -> index -> type -> documents -> fields

1. index(索引)

可以類似看成一個database,但區別於就是一個擁有幾分相似特徵的文檔的集合,比如你可以有商品數據索引、或則客戶數據索引。

2. type(類型)

可以類似看成一個table,就是給文檔分分類用的,通常,會為具有一組共同字段的文檔定義一個類型。

3. documents (文檔)

可以類似看成一個table下一行數據, 一個文檔是一個可被索引的基礎信息單元。

4. fields(字段,在lucene中叫域)

可以類似看成一個table的字段,對文檔數據根據不同屬性進行的分類標識

5. mapping(映射)

可以類似看成字段的數據類型和約束,mapping是處理數據的方式和規則方面做一些限制,如某個字段的數據類型、默認值、分析器、是否被索引等等

6. shards&replicas(分片&備份)

ES是分佈式大數據量全文檢索服務器,把文檔數據切成片段,多個片合在一起是一個完整的數據。在分佈式環境中很有就能出現單點故障問題,這時候需要備份每個片段會被複制和轉移同步。

一篇就懂 Elasticsearch | 原力计划

RESTfull語法

我這裡使用kibana,也可以使用其他工具實現

1. 創建索引index和映射mapping

 1PUT /索引名
2
3{
4
5 "mappings": {
6
7 "type名": {
8
9 "properties": {
10
11 "fields名": {
12
13 "type": "類型",
14
15 "store": 是否儲存[true,false],
16
17 "index": 是否索引[true,false],
18
19 "analyzer":"分詞器"
20
21 },
22
23 "fields名": {
24
25 "type": "text",
26
27 "store": true,
28
29 "index": true,
30
31 "analyzer":"standard"
32
33 }
34
35 }
36
37 }
38

39 }
40
41}

2. 創建索引index後添加映射mapping

 1POST /索引名/type名/_mapping
2
3{
4
5 "type名":{
6
7 "properties":{
8
9 "fields名":{
10
11 "type":"long",
12
13 "store":true,
14
15 "index":false
16
17 },
18
19 "fields名":{
20
21 "type":"text",
22
23 "store":true,
24
25 "index":true,
26
27 "analyzer":"standard"
28
29 }
30
31 }
32
33 }
34
35}

3. 刪除索引index

1DELETE /索引名

4. 添加文檔document

 1POST /索引名/type名/[_id]
2
3{
4
5"FIELD": "VALUE",
6
7"FIELD": "VALUE",
8
9"FIELD": "VALUE"
10
11}

5. 修改文檔document

1和添加相同,並且_id存在

6. 刪除文檔document

1DELETE /索引名/type名/_id

7. 根據_id查詢

1GET /索引名/type名/_id

8. 根據term查詢

 1POST /索引名/type名/_search
2
3{
4
5 "query": {
6
7 "term": {
8
9 "FIELD": "VALUE"
10
11 }

12
13 }
14
15}

9. 根據query_string查詢

 1POST /索引名/type名/_search
2
3{
4
5 "query": {
6
7 "query_string": {
8
9 "default_field": "FIELD",
10
11 "query": "this AND that OR thus"
12
13 }
14
15 }
16
17}
一篇就懂 Elasticsearch | 原力计划

IK分詞器

查看分詞效果

1GET /_analyze
2
3{
4
5 "analyzer": "standard",
6
7 "text":"VALUE"
8
9}

集成IK分詞器

  1. 下載IK分詞器壓縮包並解壓縮

  2. 把其中elasticsearch文件夾改名ik-analyzer

  3. 把ik-analyzer文件夾放置在elasticsearch目錄的plugins文件夾

  4. 重啟elasticsearch服務器

  5. 測試分詞器效果,把analyzer的值改成ik_smart 或 ik_max_word

一篇就懂 Elasticsearch | 原力计划

Elasticsearch集群

這裡ES集群相當簡單,它不像solr需要一個註冊中心,其實玩過分佈式童鞋都知道,玩集群無非多開幾個實例並用一個或多個註冊中心管理起來。而ES集群模式使用一個 P2P類型(使用 gossip 協議)的分佈式系統,說白了就是一個廣播分佈式系統。所以配置起來比外帶註冊中心簡單。

1. cluster(集群)

一個集群就是由一個或多個節點組織在一起,它們共同持有整個的數據,並一起提供索引和搜索功能。一個集群由一個唯一的名字標識,這個名字默認就是“elasticsearch”。這個名字是重要的,因為一個節點只能通過指定某個集群的名字,來加入這個集群。

2. node(節點)

就是一個集群的服務器

3. shards&replicas(分片&備份)

準備多臺ES服務器,修改elasticsearch-cluster\\config\\elasticsearch.yml配置文件

 1#節點n的配置信息:
2
3#集群名稱,保證唯一
4
5cluster.name: elasticsearch
6
7#節點名稱,必須不一樣
8
9node.name: node-1
10
11#必須為本機的ip地址
12
13network.host: 127.0.0.1
14
15#服務端口號,在同一機器下必須不一樣
16
17http.port: 9200
18
19#集群間通信端口號,在同一機器下必須不一樣
20
21transport.tcp.port: 9300
22
23#設置集群自動發現機器ip集合
24
25discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
一篇就懂 Elasticsearch | 原力计划

JAVA客戶端

7.1 創建Maven工程,導入座標

 1<dependencies>
2
3 <dependency>
4
5 <groupid>org.elasticsearch/<groupid>
6
7 <artifactid>elasticsearch/<artifactid>
8
9 <version>5.6.10/<version>
10
11 /<dependency>
12
13 <dependency>
14

15 <groupid>org.elasticsearch.client/<groupid>
16
17 <artifactid>transport/<artifactid>
18
19 <version>5.6.10/<version>
20
21 /<dependency>
22
23 <dependency>
24
25 <groupid>org.apache.logging.log4j/<groupid>
26
27 <artifactid>log4j-to-slf4j/<artifactid>
28
29 <version>2.9.1/<version>
30
31 /<dependency>
32
33 <dependency>
34
35 <groupid>org.slf4j/<groupid>
36
37 <artifactid>slf4j-api/<artifactid>
38
39 <version>1.7.24/<version>
40
41 /<dependency>
42
43 <dependency>
44
45 <groupid>org.slf4j/<groupid>
46
47 <artifactid>slf4j-simple/<artifactid>
48
49 <version>1.7.21/<version>
50
51 /<dependency>
52
53 <dependency>
54
55 <groupid>log4j/<groupid>
56
57 <artifactid>log4j/<artifactid>
58
59 <version>1.2.12/<version>
60
61 /<dependency>
62
63 <dependency>
64

65 <groupid>junit/<groupid>
66
67 <artifactid>junit/<artifactid>
68
69 <version>4.12/<version>
70
71 /<dependency>
72
73/<dependencies>

7.2 創建索引庫

 1public class ElasticsearchClient {
2
3 @Test
4
5 public void createIndex throws Exception {
6
7// 創建settings對象
8
9 Settings settings = Settings.builder
10
11 .put("cluster.name","elasticsearch")
12
13 .build;
14
15// 創建客戶端對象
16
17 TransportClient client = new PreBuiltTransportClient(settings);
18
19 client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
20
21// 創建索引庫
22
23 client.admin.indices.prepareCreate("index_hello").get;
24
25// 關閉資源
26
27 client.close;
28
29 }
30
31}

7.3 設置映射

 1public class ElasticsearchClient {
2
3 @Test
4
5 public void setMapping throws Exception {
6
7// 創建settings對象
8
9 Settings settings = Settings.builder
10
11 .put("cluster.name","elasticsearch")
12
13 .build;
14
15// 創建客戶端對象
16
17 TransportClient client = new PreBuiltTransportClient(settings);
18
19 client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
20
21// 構建Mapping,RESTfull請求體
22
23 XContentBuilder builder = XContentFactory.jsonBuilder
24
25 .startObject
26
27 .startObject("article")
28
29 .startObject("properties")
30
31 .startObject("id")
32
33 .field("type","long")
34
35 .field("store",true)
36
37 .endObject
38
39 .startObject("title")
40
41 .field("type","text")
42
43 .field("store",true)
44
45 .field("analyzer","ik_smart")
46
47 .endObject

48
49 .startObject("content")
50
51 .field("type","text")
52
53 .field("store",true)
54
55 .field("analyzer","ik_smart")
56
57 .endObject
58
59 .endObject
60
61 .endObject
62
63 .endObject;
64
65// 使用客戶端把mapping設置到索引庫
66
67 client.admin.indices
68
69 .preparePutMapping("index_hello")
70
71 .setType("article")
72
73 .setSource(builder)
74
75 .get;
76
77// 關閉資源
78
79 client.close;
80
81 }
82
83}

7.4 添加文檔

 1public class ElasticsearchClient {
2
3 @Test
4
5 public void addDocument throws Exception {
6
7// 創建settings對象

8
9 Settings settings = Settings.builder
10
11 .put("cluster.name","elasticsearch")
12
13 .build;
14
15// 創建客戶端對象
16
17 TransportClient client = new PreBuiltTransportClient(settings);
18
19 client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),9300));
20
21 XContentBuilder builder = XContentFactory.jsonBuilder
22
23 .startObject
24
25 .field("id",1L)
26
27 .field("title","商務部:有序有力組織商貿企業復工復產")
28
29 .field("content","新華社北京2月23日電(記者陳煒偉、王雨蕭)記者23日從商務部瞭解到,商務部印發《關於統籌做好生活必需品供應保障有關工作的通知》,要求各地商務主管部門在確保疫情防控安全的前提下,有序有力組織商貿企業復工復產。")
30
31 .endObject;
32
33// 發送到服務器
34
35 client.prepareIndex("index_hello","article","1")
36
37 .setSource(builder)
38
39 .get;
40
41// 關閉資源
42
43 client.close;
44

45
46
47 }
48
49}

7.5 查詢(核心功能)

  • 根據_Id查詢

  • 根據Term查詢

  • 根據QueryString查詢

  • 設置分頁(在執行查詢之前SearchResponse中方法setFrom和setSize)

  • 設置高亮

 1public class SearchIndex {
2
3 private TransportClient client;
4
5 @Before
6
7 public void initthrows Exception {
8
9// 創建settings對象
10
11 Settings settings = Settings.builder
12
13 .put("cluster.name", "elasticsearch")
14

15 .build;
16
17// 創建客戶端對象
18
19 client = new PreBuiltTransportClient(settings);
20
21 client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
22
23 }
24
25 @Test
26
27 public void searchById{
28
29// 創建查詢對象
30
31 QueryBuilder queryBuilder = QueryBuilders.idsQuery.addIds("1","2");
32
33// 執行查詢
34
35 SearchResponse searchResponse = client.prepareSearch("index_hello")
36
37 .setTypes("article")
38
39 .setQuery(queryBuilder)
40
41 .get;
42
43// 獲取總記錄數
44
45 SearchHits hits = searchResponse.getHits;
46
47 System.out.println("總記錄數:"+hits.getTotalHits);
48
49// 結果列表
50
51 Iterator<searchhit> iterator = hits.iterator;
52
53 while (iterator.hasNext){
54
55 SearchHit next = iterator.next;
56
57 Map<string> source = next.getSource;
58
59 System.out.println("id:"+source.get("id"));
60
61 System.out.println("title:"+source.get("title"));

62
63 System.out.println("content:"+source.get("content"));
64
65 System.out.println("----------------------------------");
66
67 }
68
69
70
71 }
72
73 @Test
74
75 public void searchByTerm{
76
77// 創建查詢對象
78
79 QueryBuilder queryBuilder = QueryBuilders.termQuery("title","復工");
80
81// 執行查詢
82
83 SearchResponse searchResponse = client.prepareSearch("index_hello")
84
85 .setTypes("article")
86
87 .setQuery(queryBuilder)
88
89 .get;
90
91// 獲取總記錄數
92
93 SearchHits hits = searchResponse.getHits;
94
95 System.out.println("總記錄數:"+hits.getTotalHits);
96
97// 結果列表
98
99 Iterator<searchhit> iterator = hits.iterator;
100
101 while (iterator.hasNext){
102
103 SearchHit next = iterator.next;
104
105 Map<string> source = next.getSource;
106
107 System.out.println("id:"+source.get("id"));
108
109 System.out.println("title:"+source.get("title"));

110
111 System.out.println("content:"+source.get("content"));
112
113 System.out.println("----------------------------------");
114
115 }
116
117
118
119 }
120
121 @Test
122
123 public void searchByQueryString{
124
125// 創建查詢對象
126
127 QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("我家住在臨安").defaultField("title");
128
129// 執行查詢
130
131 SearchResponse searchResponse = client.prepareSearch("index_hello")
132
133 .setTypes("article")
134
135 .setQuery(queryBuilder)
136
137 .setFrom(0)
138
139 .setSize(3)
140
141 .highlighter(new HighlightBuilder.field("title").preTags("").postTags(""))
142
143 .get;
144
145// 獲取總記錄數
146
147 SearchHits hits = searchResponse.getHits;
148
149 System.out.println("總記錄數:"+hits.getTotalHits);
150
151// 結果列表
152
153 Iterator<searchhit> iterator = hits.iterator;
154

155 while (iterator.hasNext){
156
157 SearchHit next = iterator.next;
158
159 Map<string> source = next.getSource;
160
161 System.out.println("id:"+source.get("id"));
162
163 System.out.println("title:"+source.get("title"));
164
165 System.out.println("content:"+source.get("content"));
166
167 System.out.println("----------------------------------");
168
169 HighlightField title = next.getHighlightFields.get("title");
170
171 System.out.println(title.getFragments[0]);
172
173 }
174
175
176
177 }
178
179 @After
180
181 public void close{
182
183 client.close;
184
185 }
186
187}
/<string>/<searchhit>/<string>/<searchhit>/<string>/<searchhit>
一篇就懂 Elasticsearch | 原力计划

Spring Data Elasticsearch

使用原始JAVA客戶端操作ES非常複雜,Spring最擅長做整合對ES的操作將會大大簡化,所以還是推薦使用Spring Data,原生的作為了解即可。

8.1 創建Maven工程,導入座標

 1 <dependencies>
2
3 <dependency>
4
5 <groupid>org.elasticsearch/<groupid>
6
7 <artifactid>elasticsearch/<artifactid>
8
9 <version>5.6.10/<version>
10
11 /<dependency>
12
13 <dependency>
14
15 <groupid>org.elasticsearch.client/<groupid>
16
17 <artifactid>transport/<artifactid>
18
19 <version>5.6.10/<version>
20
21 /<dependency>
22
23 <dependency>
24
25 <groupid>org.apache.logging.log4j/<groupid>
26
27 <artifactid>log4j-to-slf4j/<artifactid>
28
29 <version>2.9.1/<version>
30
31 /<dependency>
32
33 <dependency>
34
35 <groupid>org.slf4j/<groupid>

36
37 <artifactid>slf4j-api/<artifactid>
38
39 <version>1.7.24/<version>
40
41 /<dependency>
42
43 <dependency>
44
45 <groupid>org.slf4j/<groupid>
46
47 <artifactid>slf4j-simple/<artifactid>
48
49 <version>1.7.21/<version>
50
51 /<dependency>
52
53 <dependency>
54
55 <groupid>log4j/<groupid>
56
57 <artifactid>log4j/<artifactid>
58
59 <version>1.2.12/<version>
60
61 /<dependency>
62
63 <dependency>
64
65 <groupid>junit/<groupid>
66
67 <artifactid>junit/<artifactid>
68
69 <version>4.12/<version>
70
71 /<dependency>
72
73 <dependency>
74
75 <groupid>com.fasterxml.jackson.core/<groupid>
76
77 <artifactid>jackson-core/<artifactid>
78
79 <version>2.8.1/<version>
80
81 /<dependency>
82
83 <dependency>
84
85 <groupid>com.fasterxml.jackson.core/<groupid>

86
87 <artifactid>jackson-databind/<artifactid>
88
89 <version>2.8.1/<version>
90
91 /<dependency>
92
93 <dependency>
94
95 <groupid>com.fasterxml.jackson.core/<groupid>
96
97 <artifactid>jackson-annotations/<artifactid>
98
99 <version>2.8.1/<version>
100
101 /<dependency>
102
103 <dependency>
104
105 <groupid>org.springframework.data/<groupid>
106
107 <artifactid>spring-data-elasticsearch/<artifactid>
108
109 <version>3.0.9.RELEASE/<version>
110
111 <exclusions>
112
113 <exclusion>
114
115 <groupid>org.elasticsearch.plugin/<groupid>
116
117 <artifactid>transport-netty4-client/<artifactid>
118
119 /<exclusion>
120
121 /<exclusions>
122
123 /<dependency>
124
125 <dependency>
126
127 <groupid>org.springframework/<groupid>
128
129 <artifactid>spring-test/<artifactid>
130
131 <version>5.0.8.RELEASE/<version>
132
133 <scope>test/<scope>
134
135 /<dependency>

136
137
138
139 /<dependencies>

8.2 添加配置文件

 1
2
3<beans>4
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
7 xmlns:context="http://www.springframework.org/schema/context"
8
9 xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
10
11 xsi:schemaLocation="
12
13http://www.springframework.org/schema/beans
14
15http://www.springframework.org/schema/beans/spring-beans.xsd
16
17http://www.springframework.org/schema/context
18
19http://www.springframework.org/schema/context/spring-context.xsd
20
21http://www.springframework.org/schema/data/elasticsearch
22
23http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
24
25">
26
27
28
29 <transport-client>
30
31
32
33 <repositories>
34
35
36

37 <bean>
38
39 <constructor-arg>
40
41 /<bean>
42
43/<beans>

8.3 創建實體類,添加dao接口

 1@Document(indexName = "my_blog",type = "article")
2
3public class Article {
4
5 @Id
6
7 @Field(type = FieldType.Long)
8
9 private Long id;
10
11 @Field(type = FieldType.Text,analyzer = "ik_smart")
12
13 private String title;
14
15 @Field(type = FieldType.Text,analyzer = "ik_smart")
16
17 private String content;
18
19
20
21 public Article {
22
23 }
24
25
26
27 public Article(Long id, String title, String content) {
28
29 this.id = id;
30
31 this.title = title;
32
33 this.content = content;
34
35 }
36
37

38
39 public Long getId {
40
41 return id;
42
43 }
44
45
46
47 public void setId(Long id) {
48
49 this.id = id;
50
51 }
52
53
54
55 public String getTitle {
56
57 return title;
58
59 }
60
61
62
63 public void setTitle(String title) {
64
65 this.title = title;
66
67 }
68
69
70
71 public String getContent {
72
73 return content;
74
75 }
76
77
78
79 public void setContent(String content) {
80
81 this.content = content;
82
83 }
84
85
86
87 @Override

88
89 public String toString {
90
91 return "Article{" +
92
93 "id=" + id +
94
95 ", title='" + title + '\\'' +
96
97 ", content='" + content + '\\'' +
98
99 '}';
100
101 }
102
103}
1public interface ArticleRepository extends ElasticsearchRepository<article> {
2
3}/<article>

8.4 索引映射和文檔增刪改查

 1@RunWith(SpringRunner.class)
2
3@ContextConfiguration("classpath:applicationContext.xml")
4
5public class ESTest {
6
7 @Autowired
8
9 private ArticleRepository articleRepository;
10
11 @Autowired
12
13 private ElasticsearchTemplate template;
14
15 @Test
16
17 public void createIndex{
18
19// 創建索引並配置映射關係
20
21 template.createIndex(Article.class);
22
23// 配置映射

24
25// template.putMapping(Article.class);
26
27 }
28
29 @Test
30
31 public void addDocumentAndUpdateDocument{
32
33 Article article = new Article(2L,"時政新聞眼丨在一場罕見的電視電話會上,習近平這樣動員戰“疫”","2月23日,農曆二月初一。一場特別的會議在人民大會堂召開,分會場一直設到了縣、團。中國正在打一場疫情防控的人民戰爭、總體戰、阻擊戰。怎樣分析這場戰爭?目前打到了哪一步?如何全面打贏?親自指揮這場戰爭的習近平在這場“戰時會議”上從容作答。");
34
35// 添加文檔
36
37 articleRepository.save(article);
38
39 }
40
41 @Test
42
43 public void delDocument{
44
45// 根據Id刪除
46
47 articleRepository.deleteById(1L);
48
49// 全部刪除
50
51// articleRepository.deleteAll;
52
53 }
54
55 @Test
56
57 public void findAll{
58

59 Iterable<article> all = articleRepository.findAll;
60
61 all.forEach(a-> System.out.println(a));
62
63 }
64
65 @Test
66
67 public void findById{
68
69 Optional<article> optional = articleRepository.findById(2L);
70
71 System.out.println(optional.get);
72
73 }
74
75}/<article>/<article>

8.5 自定義查詢

在接口中定義自定義查詢,使用IDEA會有提示這裡就不做介紹

8.6 原始查詢條件查詢

 1 @Test
2
3 public void nativeSearch{
4
5 NativeSearchQuery query = new NativeSearchQueryBuilder
6
7 .withQuery(
8
9 QueryBuilders.queryStringQuery("測試一個查詢")
10
11 .defaultField("title")
12
13 ).withPageable(PageRequest.of(0,15))
14
15 .build;
16
17 AggregatedPage<article> articles = template.queryForPage(query, Article.class);
18

19 articles.forEach(a-> System.out.println(a));
20
21 }/<article>

到此ES學習已經夠項目上使用了,所以學了這門技術就不要讓他在你的大腦吃灰,趕緊應用到你們的項目中,最後祝大家技術越學越NB!

附 字段屬性字段屬性詳解type

Elasticsearch中支持的數據類型非常豐富:

一篇就懂 Elasticsearch | 原力计划

我們說幾個關鍵的:

  • String類型,又分兩種:

    • text:可分詞,不可參與聚合

    • keyword:不可分詞,數據會作為完整字段進行匹配,可以參與聚合

  • Numerical:數值類型,分兩類

    • 基本數據類型:long、interger、short、byte、double、float、half_float

    • 浮點數的高精度類型:scaled_float

      • 需要指定一個精度因子,比如10或100。elasticsearch會把真實值乘以這個因子後存儲,取出時再還原。

  • Date:日期類型

elasticsearch可以對日期格式化為字符串存儲,但是建議我們存儲為毫秒值,存儲為long,節省空間。

index

index影響字段的索引情況。

  • true:字段會被索引,則可以用來進行搜索。默認值就是true

  • false:字段不會被索引,不能用來搜索

index的默認值就是true,也就是說你不進行任何配置,所有字段都會被索引。

但是有些字段是我們不希望被索引的,比如商品的圖片信息,就需要手動設置index為false。

store

是否將數據進行額外存儲。

在學習lucene和solr時,我們知道如果一個字段的store設置為false,那麼在文檔列表中就不會有這個字段的值,用戶的搜索結果中不會顯示出來。

但是在Elasticsearch中,即便store設置為false,也可以搜索到結果。

原因是Elasticsearch在創建文檔索引時,會將文檔中的原始數據備份,保存到一個叫做_source的屬性中。而且我們可以通過過濾_source來選擇哪些要顯示,哪些不顯示。

而如果設置store為true,就會在_source以外額外存儲一份數據,多餘,因此一般我們都會將store設置為false,事實上,store的默認值就是false。

boost

激勵因子,這個與lucene中一樣

其它的不再一一講解,用的不多,大家參考官方文檔:

一篇就懂 Elasticsearch | 原力计划

原文鏈接:

https://blog.csdn.net/mr_xinchen/article/details/104231377


分享到:


相關文章: