Elasticsearch學習筆記-Delete By Query API

記錄關於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 段合併

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章