Elasticsearch學習筆記-Delete By Query API


記錄關於Elasticsearch的文檔刪除API的學習

首先官網上Document APIs介紹了 Delete API 和Delete By Query API。

Delete API
可以通過指定索引–>類型–>id的方式對文檔進行刪除

DELETE /index/type/1
1
響應body

{
    "_shards" : {
        "total" : 2,
        "failed" : 0,
        "successful" : 2
    },
    "found" : true,
    "_index" : "index",
    "_type" : "type",
    "_id" : "1",
    "_version" : 2,
    "result": "deleted"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
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"
    }
  }
}
1
2
3
4
5
6
7
8
請求體跟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" : [ ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
應用實例:
學習過刪除文檔操作之后,就要進行應用啦。由於項目是使用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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
參考:

[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 段合並


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM