1. 程式人生 > >ElasticSearch 文件及操作

ElasticSearch 文件及操作

> **公號:碼農充電站pro** > **主頁:** 本節介紹 ES 文件,索引及其基本操作。 ### 1,ES 中的文件 在 ES 中,**文件**(Document)是可搜尋資料的最小儲存單位,相當於關係資料庫中的一條記錄。 文件以 **Json** 資料格式儲存在 ES 中,Json 中儲存著多個**鍵值對**,它可以儲存不同型別的資料,比如: - 字串型別 - 數字型別 - 布林型別 - 陣列型別 - 日期型別 - 二進位制型別 - 範圍型別 > Python 語言中的**字典**型別,就是 Json 資料格式。 文件中的資料型別可以指定,也可以由 ES 自動推斷。 每個文件中都有一個 **Unique ID**,用於唯一標識一個文件。Unique ID 可以由使用者指定,也可以由 ES 自動生成。 >
**Unique ID** 實際上是一個**字串**。 比如下面的 Json 就是一個文件: ```python { "name" : "XiaoMing", "age" : 19, "gender" : "male" } ``` #### 1.1,文件元資料 將上面那個 Json 資料儲存到 ES 後,會像下面這樣: ```python { "_index": "person", "_type": "_doc", "_id": "2344563", "_version": 1, "_source": { "name": "XiaoMing", "age": 19, "gender": "male" } } ``` 其中以下劃線開頭的欄位就是元資料: - `_index`:文件所屬的索引。 - `_type`:文件的型別。ES 7.0 開始,一個索引只能有一種 `_type`。 - `_id`:文件的唯一 ID。 - `_source`:文件的原始 Json 資料。 - `_version`:文件更新的次數。 你可以檢視[這裡](https://www.elastic.co/cn/blog/moving-from-types-to-typeless-apis-in-elasticsearch-7-0),瞭解“**為什麼單個Index下,不再支援多個Tyeps?**”。 更多關於元資料的資訊,可以參考[這裡](https://www.elastic.co/guide/en/elasticsearch/reference/7.10/mapping-fields.html)。 #### 1.2,文件的刪除與更新 ES 中文件的**刪除操作不會馬上將其刪除**,而是會將其標記到 **del** 檔案中,在後期合適的時候(比如 Merge 階段)會真正的刪除。 **ES 中的文件是不可變更的**,**更新操作**會將舊的文件標記為刪除,同時增加一個新的欄位,並且文件的 version 加 1。 #### 1.3,文件中的欄位數 在 ES 中,一個文件預設最多可以有 **1000** 個欄位,可以通過 [index.mapping.total_fields.limit](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html#mapping-limit-settings) 進行設定。 注意在設計 ES 中的資料結構時,不要使文件的欄位數過多,這樣會使得 mapping 很大,增加叢集的負擔。 ### 2,ES 中的索引 ES 中的文件都會儲存在某個**索引**(Index)中,索引是文件的容器,是一類文件的集合,相當於關係型資料庫中的表的概念。 ES 中可以建立很多不同的索引,表示不同的文件集合。 每個索引都可以定義自己的 **Mappings** 和 **Settings**: - `Mappings`:用於設定文件欄位的型別。 - `Settings`:用於設定不同的資料分佈。 對於索引的一些引數設定,有些引數可以動態修改,有些引數在索引建立後不能修改,可參考[這裡](https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index-modules.html)。 ***ES 與傳統資料庫類比*** 如果將 ES 中的基本概念類比到傳統資料庫中,它們的對應關係如下: | ES | 傳統資料庫 | | ------- | ---------- | | 索引 | 表 | | 文件 | 行 | | 欄位 | 列 | | Mapping | 表定義 | | DSL | SQL 語句 | ***索引相關 API*** 下面給出一些檢視索引相關資訊的 API: ```shell # 檢視索引相關資訊 GET index_name # 檢視索引的文件總數 GET index_name/_count # 檢視指定索引的前10條文件 POST index_name/_search { } #_cat indices API # 檢視所有的索引名以 index_prefix 為字首的索引 GET /_cat/indices/index_prefix*?v&s=index # 檢視狀態為 green 的索引 GET /_cat/indices?v&health=green # 按照文件個數排序 GET /_cat/indices?v&s=docs.count:desc # 檢視指定索引的指定資訊 GET /_cat/indices/index_prefix*?pri&v&h=health,index,pri,rep,docs.count,mt # 檢視索引使用的記憶體大小 GET /_cat/indices?v&h=i,tm&s=tm:desc ``` ### 3,GET 操作 **GET** 操作可以獲取指定文件的內容。 `GET index_name/_count`:獲取指定索引中的文件數。 `GET index_name/_doc/id`:獲取指定索引中的指定文件。 `GET index_name/_doc`:**不允許**該操作。 `GET index_name`:獲取指定索引的 `Mappings` 和 `Settings`。 ### 4,POST / PUT 操作 **POST/PUT** 操作用於建立文件。 ***按照 POST / PUT 方法來區分*** `POST index_name/_doc`: - `POST index_name/_doc`:不指定 ID,總是會插入新的文件,文件數加 1。 - `POST/PUT index_name/_doc/id`:指定 ID - 當 id 存在時,會覆蓋之前的,並且 version 會加 1,文件數不增加。 - 當 id 不存在時,會插入新的文件,文件數加 1。 `PUT index_name/_create`: - `PUT index_name/_create`:不指定 ID,**不允許**該操作。 - `PUT index_name/_create/id`:指定 ID - 當 id 存在時:**報錯**,不會插入新文件。 - 當 id 不存在時:,會插入新的文件,文件數加 1。 `PUT index_name/_doc`: - `PUT index_name/_doc`:不指定 ID,**不允許**該操作。 - `PUT/POST index_name/_doc/id`:指定 ID - 當 id 存在時,會覆蓋之前的,並且 version 會加 1,文件數不增加。 - 當 id 不存在時,會插入新的文件,文件數加 1。 `PUT index_name/_doc/id?op_type=XXX` - `op_type=create`: - 當 id 存在時,**報錯**,不會插入新文件。 - 當 id 不存在時,會插入新的文件,文件數加 1。 - `op_type=index`: - 當 id 存在時,會覆蓋之前的,並且 version 會加 1,文件數不增加。 - 當 id 不存在時,會插入新的文件,文件數加 1。 ***按照是否指定 ID 來區分*** **指定 ID**: - `POST/PUT index_name/_doc/id`:指定 ID,稱為 **Index** 操作 - 相當於 `PUT index_name/_doc/id?op_type=index` - 當 id 存在時,會覆蓋之前的,並且 version 會加 1,文件數不增加。 - 當 id 不存在時,會插入新的文件,文件數加 1。 - `PUT index_name/_doc/id?op_type=create`:指定 ID,稱為 **Create** 操作 - 相當於 `PUT index_name/_create/id` - 當 id 存在時,**報錯**,不會插入新文件。 - 當 id 不存在時,會插入新的文件,文件數加 1。 **不指定 ID**: - `POST index_name/_doc`:不指定 ID,總是會插入新的文件,文件數加 1。 - `PUT index_name/_doc`:不指定 ID,**不允許**該操作。 - `PUT index_name/_create`:不指定 ID,**不允許**該操作。 ### 5,Update 操作 Update 操作用於更新文件的內容。 `POST index_name/_update/id/`:更新指定文件的內容。更新的內容要放在 **doc** 欄位中,否則會**報錯**。 - 當 id 不存在時,報錯,不更新任何內容。 - 當 id 存在時: - 如果更新的欄位與**原來的相同**,則不做任何操作。 - 如果更新的欄位與**原來的不同**,則更新原有內容,並且 version 會加 1。 實際上 ES 中的文件是不可變更的,更新操作會將舊的文件標記為刪除,同時增加一個新的欄位,並且文件的 version 加 1。 ### 6,Delete 操作 Delete 操作用於刪除索引或文件。 `DELETE /index_name/_doc/id`:刪除某個文件。 - 當刪除的 id 存在時,會刪除該文件。 - 當刪除的 id 不存在時,ES 會返回 `not_found`。 `DELETE /index_name`:刪除整個索引,**要謹慎使用**! - 當刪除的 index_name 存在時,會刪除整個索引內容。 - 當刪除的 index_name 不存在時,ES 會返回 `404` 錯誤。 ### 7,Bulk 批量操作 批量操作指的是,在一次 API 呼叫中,對不同的索引進行多次操作。 每次操作互不影響,即使某個操作出錯,也不影響其他操作。 返回的結果中包含了所有操作的執行結果。 Bulk 支援的操作有 `Index`,`Create`,`Update`,`Delete`。 Bulk 操作的格式如下: ```shell POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" } { "delete" : { "_index" : "test", "_id" : "2" } } { "create" : { "_index" : "test2", "_id" : "3" } } { "field1" : "value3" } { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} } ``` 注意 Bulk 請求體的資料量不宜過大,建議在 5~15M。 ### 8,Mget 批量讀取 **Mget** 一次讀取多個文件的內容,設計思想類似 Bulk 操作。 Mget 操作的格式如下: ```shell GET _mget { "docs" : [ {"_index" : "index_name1", "_id" : "1"}, {"_index" : "index_name2", "_id" : "2"} ] } ``` 也可以在 URI 中指定索引名稱: ```shell GET /index_name/_mget { "docs" : [ {"_id" : "1"}, {"_id" : "2"} ] } ``` 還可以用 `_source` 欄位來設定返回的內容: ```shell GET _mget { "docs" : [ {"_index" : "index_name1", "_id" : "1"}, {"_index" : "index_name2", "_id" : "2", "_source" : ["f1", "f2"]} ] } ``` ### 9,Msearch 批量查詢 **Msearch** 操作用於批量查詢,格式如下: ```shell POST index_name1/_msearch {} # 索引名稱,不寫的話就是 URI 中的索引 {"query" : {"match_all" : {}},"size":1} {"index" : "index_name2"} # 改變了索引名稱 {"query" : {"match_all" : {}},"size":2} ``` URI 中也可以不寫索引名稱,此時**請求體**裡必須寫索引名稱: ```shell POST _msearch {"index" : "index_name1"} # 索引名稱 {"query" : {"match_all" : {}},"size":1} {"index" : "index_name2"} # 索引名稱 {"query" : {"match_all" : {}},"size":2} ``` 上文中介紹了 3 種批量操作,分別是 Bulk,Mget,Msearch。注意在使用批量操作時,資料量不宜過大,避免出現**效能問題**。 ### 10,ES 常見錯誤碼 當我們的請求發生錯誤的時候,ES 會返回相應的**錯誤碼**,常見的錯誤碼如下: | 錯誤碼 | 含義 | | ------ | ------------ | | 429 | 叢集過於繁忙 | | 4XX | 請求格式錯誤 | | 500 | 叢集內部錯誤 | ### 11,Reindex 重建索引 有時候我們需要**重建索引**,比如以下情況: - 索引的 `mappings` 發生改變:比如欄位型別或者分詞器等發生更改。 - 索引的 `settings` 發生改變:比如索引的主分片數發生更改。 - 叢集內或叢集間需要做**資料遷移**。 ES 中提供兩種重建 API: - [Update by query](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html):在現有索引上重建索引。 - [Reindex](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html):在其它索引上重建索引。 #### 11.1,新增子欄位 先在一個索引中插入資料: ```shell DELETE blogs/ # 寫入文件 PUT blogs/_doc/1 { "content":"Hadoop is cool", "keyword":"hadoop" } # 檢視自動生成的 Mapping GET blogs/_mapping # 查詢文件 POST blogs/_search { "query": { "match": { "content": "Hadoop" } } } # 可以查到資料 ``` 現在修改 **mapping**(**新增子欄位**是允許的),為 **content** 欄位加入一個子欄位: ```shell # 修改 Mapping,增加子欄位,使用英文分詞器 PUT blogs/_mapping { "properties" : { "content" : { # content 欄位 "type" : "text", "fields" : { # 加入一個子欄位 "english" : { # 子欄位名稱 "type" : "text", # 子欄位型別 "analyzer":"english" # 子欄位分詞器 } } } } } # 檢視新的 Mapping GET blogs/_mapping ``` 修改 **mapping** 之後再查詢文件: ```shell # 使用 english 子欄位查詢 Mapping 變更前寫入的文件 # 查不到文件 POST blogs/_search { "query": { "match": { "content.english": "Hadoop" } } } # 注意:不使用 english 子欄位是可以查詢到之前的文件的 POST blogs/_search { "query": { "match": { "content": "Hadoop" } } } ``` 結果發現,使用 **english** 子欄位是查不到之前的文件的。這時候就需要**重建索引**。 #### 11.2,Update by query 下面使用 `Update by query` 對索引進行重建: ```shell # Update所有文件 POST blogs/_update_by_query { } ``` 重建索引之後,不管是使用 **english** 子欄位還是不使用,都可以查出文件。 `Update by query` 操作還可以設定一些條件: - [uri-params](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#docs-update-by-query-api-query-params) - [request-body](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#docs-update-by-query-api-request-body):通過設定一個 **query** 條件,來指定對哪些資料進行重建。 **request-body** 示例: ```shell POST tech_blogs/_update_by_query?pipeline=blog_pipeline { "query": { # 將 query 的查詢結果進行重建 "bool": { "must_not": { "exists": {"field": "views"} } } } } ``` #### 11.3,修改欄位型別 在原有 **mapping** 上,**修改欄位型別**是不允許的: ```shell # 會發生錯誤 PUT blogs/_mapping { "properties" : { "content" : { "type" : "text", "fields" : { "english" : { "type" : "text", "analyzer" : "english" } } }, "keyword" : { # 修改 keyword 欄位的型別 "type" : "keyword" } } } ``` 這時候只能建立一個新的索引,設定正確的欄位型別,然後再將原有索引中的資料,重建到新索引中。 建立一個新的索引 **blogs_new**: ```shell # 建立新的索引並且設定新的Mapping PUT blogs_new/ { "mappings": { "properties" : { "content" : { "type" : "text", "fields" : { "english" : { "type" : "text", "analyzer" : "english" } } }, "keyword" : { "type" : "keyword" } } } } ``` #### 11.4,Reindex 下面使用 **Reindex** 將原來索引中的資料,匯入到新的索引中: ```shell # Reindx API POST _reindex { "source": { # 指定原有索引 "index": "blogs" }, "dest": { # 指定目標索引 "index": "blogs_new" } } ``` **Reindex** API 中的 **source** 欄位和 **dest** 欄位還有很多引數可以設定,具體可參考[其官方文件](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html#docs-reindex-api-request-body)。 另外 **Reindex** 請求的 URI 中也可以設定引數,可以參考[這裡](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html#docs-reindex-api-query-params)。 ### 12,ES 的併發控制 同一個資源在多併發處理的時候,會發生衝突的問題。 傳統資料庫(比如 MySQL)會採用**鎖**的方式,在更新資料的時候對資料進行加鎖,來防止衝突。 而 ES 並沒有採用鎖,而是將併發問題交給了使用者處理。 在 ES 中可以採用兩種方式: - 內部版本控制(ES 自帶的 version):在 URI 中使用 `if_seq_no` 和 `if_primary_term` - 外部版本控制(由使用者指定 version):在 URI 中使用 `version` 和 `version_type=external` 示例,首先插入資料: ```shell DELETE products PUT products/_doc/1 { "title":"iphone", "count":100 } # 上面的插入操作會返回 4 個欄位: #{ # "_id" : "1", # "_version" : 1, # "_seq_no" : 0, # "_primary_term" : 1 #} ``` #### 12.1,內部版本控制方式 使用內部版本控制的方式: ```shell PUT products/_doc/1?if_seq_no=0&if_primary_term=1 { "title":"iphone", "count":100 } # 上面的更新操作返回下面內容: #{ # "_id" : "1", # "_version" : 2, # 加 1 # "_seq_no" : 1, # 加 1 # "_primary_term" : 1 # 不變 #} ``` 如果再次執行這句更新操作,則會出錯,**出錯之後由使用者決定如何處理**,**這就達到了解決衝突的目的**。 ```shell # 再執行則會出錯,因為 seq_no=0 且 primary_term=1 的資料已經不存在了 PUT products/_doc/1?if_seq_no=0&if_primary_term=1 ``` #### 12.2,外部版本控制方式 先看下資料庫中的資料: ```shell GET products/_doc/1 # 返回: { "_index" : "products", "_type" : "_doc", "_id" : "1", # id "_version" : 2, # version "_seq_no" : 1, "_primary_term" : 1, "found" : true, "_source" : { "title" : "iphone", "count" : 100 } } ``` 使用外部版本控制的方式: ```shell # 如果 URI 中的 version 值與 ES 中的 version 值相等,則出錯 # 下面這句操作會出錯,出錯之後,由使用者決定如何處理 PUT products/_doc/1?version=2&version_type=external { "title":"iphone", "count":1000 } # 如果 URI 中的 version 值與 ES 中的 version 值不相等,則成功 # 下面這句操作會成功 PUT products/_doc/1?version=3&version_type=external { "title":"iphone", "count":1000 } ``` ### 13,使用 Ingest 節點對資料預處理 [Ingest 節點](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html)用於對**資料預處理**,它是在 **ES 5.0** 後引入的一種節點型別,可以達到一定的 **Logstash** 的功能。 預設情況下,所有的節點都是 **Ingest** 節點。 **Ingest** 節點通過新增一些 [processors](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-processors.html) 來完成特定的處理,**Pipeline** 可以看做是一組 processors 的順序執行。 **Ingest** 節點的處理階段如下圖所示: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210123184845767.png) #### 13.0,Ingest 節點與 Logstash 對比 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210123232248395.png) #### 13.1,內建的 Processors ES 中內建了很多現成的 **Processors** 供我們使用: - [Append](https://www.elastic.co/guide/en/elasticsearch/reference/current/append-processor.html):向一個**陣列型別**的欄位加入更多的值。 - [Split](https://www.elastic.co/guide/en/elasticsearch/reference/current/split-processor.html):將字串拆分成陣列。 - [Set](https://www.elastic.co/guide/en/elasticsearch/reference/current/set-processor.html):設定一個欄位。 - [Uppercase](https://www.elastic.co/guide/en/elasticsearch/reference/current/uppercase-processor.html):大寫轉換。 - [Lowercase](https://www.elastic.co/guide/en/elasticsearch/reference/current/lowercase-processor.html):小寫轉換。 - [Remove](https://www.elastic.co/guide/en/elasticsearch/reference/current/remove-processor.html):移除一個已存在的欄位。如果欄位不存在,將丟擲異常。 - [Rename](https://www.elastic.co/guide/en/elasticsearch/reference/current/rename-processor.html):為一個欄位重新命名。 - [Convert](https://www.elastic.co/guide/en/elasticsearch/reference/current/convert-processor.html):轉換一個欄位的資料型別。比如將字串型別轉換成整數型別。 - [Date](https://www.elastic.co/guide/en/elasticsearch/reference/current/date-processor.html):日期格式轉換。 - [JSON](https://www.elastic.co/guide/en/elasticsearch/reference/current/json-processor.html):將 json 字串轉換成 **JSON** 型別。 - [Date-index-name](https://www.elastic.co/guide/en/elasticsearch/reference/current/date-index-name-processor.html):將通過該處理器的文件,分配到指定時間格式的索引中。 - [Fail](https://www.elastic.co/guide/en/elasticsearch/reference/current/fail-processor.html):當出現異常的時候,將指定的資訊返回給使用者。 - [Foreach](https://www.elastic.co/guide/en/elasticsearch/reference/current/foreach-processor.html):用於處理陣列型別的資料。 - [Pipeline](https://www.elastic.co/guide/en/elasticsearch/reference/current/pipeline-processor.html):引用另一個 Pipeline。 - [Trim](https://www.elastic.co/guide/en/elasticsearch/reference/current/trim-processor.html):刪除字元換的前置和後置空格。 - [Sort](https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-processor.html):對陣列中的元素排序。 - [Url-decode](https://www.elastic.co/guide/en/elasticsearch/reference/current/urldecode-processor.html):對字串進行 URL 解碼。 - [User-agent](https://www.elastic.co/guide/en/elasticsearch/reference/current/user-agent-processor.html):用於解析 User-Agent 資訊。 - [Html-strip](https://www.elastic.co/guide/en/elasticsearch/reference/current/htmlstrip-processor.html):用於移除 HTML 標籤。 - [Script](https://www.elastic.co/guide/en/elasticsearch/reference/current/script-processor.html):用 [Painless](https://www.elastic.co/guide/en/elasticsearch/painless/current/index.html) 語言編寫指令碼,以支援更復雜的功能。 - **Painless** 語言是專門為 ES 設計的,在 **ES 5.x** 引入,具有高效能和安全性。 - **ES 6.0** 開始,ES 只支援 Painless 指令碼,不再支援其它語言指令碼(比如 JavaScript,Python 等)。 - **Painless** 基於 **Java** 語言,並支援所有的 Java 資料型別。 - 等 #### 13.2,測試 Processors ES 中提供了一個 [simulate](https://www.elastic.co/guide/en/elasticsearch/reference/current/simulate-pipeline-api.html) 介面,用於測試 Processors。 示例: ```shell POST _ingest/pipeline/_simulate { "pipeline": { # 定義 pipeline "description": "to split blog tags", # 描述 "processors": [ # 一系列的 processors { "split": { # 一個 split processor "field": "tags", "separator": "," # 用逗號分隔 } }, { "set":{ # 可以設定多個 processor "field": "views", "value": 0 } } ] }, "docs": [ # 測試的文件 { # 第 1 個文件 "_index": "index", "_id": "id", "_source": { "title": "Introducing big data......", "tags": "hadoop,elasticsearch,spark", "content": "You konw, for big data" } }, { # 第 2 個文件 "_index": "index", "_id": "idxx", "_source": { "title": "Introducing cloud computering", "tags": "openstack,k8s", "content": "You konw, for cloud" } } ] } ``` #### 13.3,新增一個 Pipeline 當 Processors 測試通過後,可以向 ES 中新增(設定)一個 Pipeline,語法: ```shell # blog_pipeline 為 pipeline 名稱 PUT _ingest/pipeline/blog_pipeline { "description": "a blog pipeline", "processors": [ { "split": { # 第 1個 Processor "field": "tags", "separator": "," } }, { "set":{ # 第 2個 Processor "field": "views", "value": 0 } } ] } ``` #### 13.4,檢視 Pipeline ```shell # 檢視 Pipleline GET _ingest/pipeline/blog_pipeline # 刪除 Pipleline DELETE _ingest/pipeline/blog_pipeline ``` #### 13.5,測試 Pipeline ```shell # blog_pipeline 是 Pipeline 名稱 POST _ingest/pipeline/blog_pipeline/_simulate { "docs": [ { # 一個文件 "_source": { "title": "Introducing cloud computering", "tags": "openstack,k8s", "content": "You konw, for cloud" } } ] } ``` #### 13.6,使用 Pipeline 使用 **Pipeline** 插入文件時,文件會先經過 Pipeline 的處理,然後再插入到 ES 中。 ```shell # URI 中指定了 Pipeline 的名字 PUT tech_blogs/_doc/2?pipeline=blog_pipeline { "title": "Introducing cloud computering", "tags": "openstack,k8s", "content": "You konw, for cloud" } ``` 最終插入的文件是這樣的: ```shell { "title": "Introducing cloud computering", "tags": ["openstack", "k8s"], "content": "You konw, for cloud", "views": 0 } ``` 另外 [update-by-query](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html)(重建索引)的 URI 中也可以設定 [pipeline 引數](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#docs-update-by-query-api-query-params)來使用一個 **Pipeline**。 ### 14,總結 上文介紹到的所有操作,可以參考 [ES 的官方文件](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html)。 (本節完。) --- **推薦閱讀:** [ElasticSearch 查詢](https://www.cnblogs.com/codeshell/p/14389415.html) [ElasticSearch 分詞器](https://www.cnblogs.com/codeshell/p/14389403.html) [ElasticSearch 搜尋引擎概念簡介](https://www.cnblogs.com/codeshell/p/14389383.html) [Kibana,Logstash 和 Cerebro 的安裝執行](https://www.cnblogs.com/codeshell/p/14376759.html) [ElasticSearch 安裝與執行](https://www.cnblogs.com/codeshell/p/14371473.html) --- *歡迎關注作者公眾號,獲取更多技術乾貨。* ![碼農充電站pro](https://img-blog.csdnimg.cn/20200505082843773.png?#pic