是的,Elasticsearch 中的 `PUT` 請求是覆蓋式的。當你使用 `PUT` 請求向索引中寫入文檔時,如果文檔已經存在,Elasticsearch 會完全替換整個文檔的內容,而不是進行部分更新。
?
覆蓋式的具體行為
- 文檔存在時:`PUT` 請求會用新提供的 JSON 數據完全替換掉舊文檔的內容。
- 文檔不存在時:`PUT` 請求會創建一個新的文檔,并使用提供的 JSON 數據作為文檔內容。
?
示例
假設你有一個文檔,初始內容如下:
?
```json
{
? "name": "John Doe",
? "age": 25,
? "email": "john.doe@example.com"
}
```
?
現在,你使用 `PUT` 請求更新這個文檔:
?
```json
PUT /users/_doc/1
{
? "age": 30,
? "email": "john.doe@example.com"
}
```
?
更新后,文檔的內容將變為:
?
```json
{
? "age": 30,
? "email": "john.doe@example.com"
}
```
?
注意,`name` 字段在新的 `PUT` 請求中沒有被包含,因此它被移除了。整個文檔的內容被完全替換為新的 JSON 數據。
?
使用場景
- 完全替換文檔:當你需要更新文檔的大部分內容,或者完全重新定義文檔時,`PUT` 是一個合適的選擇。
- 創建新文檔:當你不確定文檔是否存在時,`PUT` 也可以用來創建新文檔。
?
注意事項
- 數據丟失風險:由于 `PUT` 是覆蓋式的,如果你沒有在請求中包含某些字段,這些字段將被刪除。因此,在使用 `PUT` 時,需要確保請求中包含了所有需要保留的字段。
- 并發問題:在多用戶并發更新同一文檔的場景中,`PUT` 可能會導致數據丟失或沖突。為了避免這種情況,可以使用 `if_seq_no` 和 `if_primary_term` 參數來實現樂觀鎖。
?
示例:使用樂觀鎖
為了避免并發沖突,可以在 `PUT` 請求中使用 `if_seq_no` 和 `if_primary_term` 參數:
?
```json
PUT /users/_doc/1?if_seq_no=1&if_primary_term=1
{
? "age": 30,
? "email": "john.doe@example.com"
}
```
?
如果文檔的序列號(`seq_no`)或主版本號(`primary_term`)與提供的值不匹配,Elasticsearch 將拒絕此次更新操作,從而避免覆蓋其他用戶的更改。
?
總結來說,`PUT` 請求是覆蓋式的,它會完全替換文檔的內容。在使用時,需要謹慎處理數據,避免意外丟失字段。