記錄關於Elasticsearch的文檔刪除API的學習
首先官網上Document APIs介紹了 Delete API 和Delete By Query API。
Delete API
可以通過指定索引–>類型–>id的方式對文檔進行刪除
DELETE /index/type/1
響應body
{
"_shards" : {
"total" : 2,
"failed" : 0,
"successful" : 2
},
"found" : true,
"_index" : "index",
"_type" : "type",
"_id" : "1",
"_version" : 2,
"result": "deleted"
}
Versioning
每個文檔都會對應一個版本,當我們執行刪除操作時,版本號也要指定。來確保執行刪除時,沒有同時執行寫入操作。不論是寫入操作還是刪除操作,都會對文檔的版本進行更改。所以當我們使用這個Delete API刪除文檔時,並不是真正意義上的刪除,只是版本變化並且對文檔增加了刪除標記。當我們再次搜索的時候,會搜索全部然後過濾掉有刪除標記的文檔。如果數據量大的話,對搜索的性能有一定的影響。必須對它進行物理刪除。
物理刪除方法:
談到物理刪除,就是把刪除的文檔信息從磁盤空間中去掉。還需要了解Elasticsearch官方文檔的Indices APIs的Indices Segments。
Indeices Segments(段)
它是用於構建Lucene索引(碎片級)的低級段信息,提供關於碎片和索引狀態的更多信息,可能是優化信息、刪除時“浪費”的數據等等。
Segments有一個關於刪除文檔的重要屬性就是,被標記刪除的文檔存儲在Segment中。如果這個數量大於0是完全可以的,那麼在合併這個segment 時將回收空間。
因此如果我們想進行物理刪除,必須進行段合併。理論上是Elasticsearch會自己進行段合併,但是合併的數量隨機,很難保證將標記刪除的文檔的段進行合併。因此需要進行配置。
Delete By Query API
除了指定刪除之外,官網還提供了根據查詢條件進行文檔刪除。
POST twitter/_delete_by_query
{
"query": {
"match": {
"message": "some message"
}
}
}
請求體跟Search API是一樣的
響應Body
{
"took" : 147,
"timed_out": false,
"deleted": 119,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1.0,
"throttled_until_millis": 0,
"total": 119,
"failures" : [ ]
}
應用實例:
學習過刪除文檔操作之後,就要進行應用啦。由於項目是使用java,對Elasticsearch文檔進行操作的。因此要對Elasticsearch Client進行選型。TransportClient
遲早要gg,因此果斷選擇java REST Client
(優點:1.可以使用TransportClient
功能 2.可以向前兼容Elasticsearch版本集羣)。但是在REST Client 6.5之前,官網是沒有對Delete By Query API進行介紹的,也就是說想使用按照搜索方式刪除文檔,需要藉助TransportClient
。這裏我們可以直接使用REST Client 6.5
REST Client ----Delete By Query API
代碼:
//創建客戶端
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("192.168.XXX.XX", 9200, "http"))
.setMaxRetryTimeoutMillis(X * 60 * 1000) //超時時間設爲X分鐘
);
//查詢要刪除的文檔
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest("_all");
deleteByQueryRequest.setConflicts("proceed");
request.setQuery(new TermQueryBuilder("user", "kimchy"));
deleteByQueryRequest.setSize(size);
BulkByScrollResponse bulkResponse = client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
//合併段,進行物理刪除
ForceMergeRequest requestAll = new ForceMergeRequest();
requestAll.maxNumSegments(1);
requestAll.onlyExpungeDeletes(true);
ForceMergeResponse forceMergeResponse = client.indices().forcemerge(requestAll, RequestOptions.DEFAULT);
參考:
[1] https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docs-delete.html elasticsearch5.6官網
[2] https://www.elastic.co/guide/en/elasticsearch/reference/5.6/indices-forcemerge.html elasticsearch5.6官網
[3] https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-delete-by-query.html REST Client 6.5 delete by query
[4] https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-force-merge.html
REST Client 6.5 段合併