ElasticSearch 文件及操作
阿新 • • 發佈:2021-02-22
> **公號:碼農充電站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