ElasticSearch 6.3版本 Document APIs之Reindex API

Reindex API

聲明:本文根據ES官方文檔進行翻譯與總結而得。轉載請註明作者:https://blog.csdn.net/qingmou_csdn

注意:Reindex不會嘗試設置目標索引。它不會複製源索引的設置。您應該在運行_reindex操作之前設置目標索引,包括設置映射,分片計數,副本等。

最基本的形式_reindex只是將文檔從一個索引複製到另一個索引。如將gaoyh索引中的文檔複製到test索引中:

POST _reindex
{
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "test"
  }
}
響應結果:
{
  "took": 161,
  "timed_out": false,
  "total": 5,
  "updated": 0,
  "created": 5,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}
注意:
就像_update_by_query_reindex獲取源索引的快照但其目標必須是不同的索引,因此不太可能發生版本衝突。該dest元素可以像Index API一樣配置,以控制樂觀併發控制。只是遺漏 version_type(如上所述)或將其設置爲internal將導致Elasticsearch盲目地將文檔轉儲到目標中,覆蓋任何碰巧具有相同類型和id的文件:
POST _reindex
{
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "test",
    "version_type": "internal"
  }
}
設置version_typeexternal將導致Elasticsearch保留 version源,創建缺少的任何文檔,並更新目標索引中具有舊版本的文檔而不是源索引中的任何文檔:
POST _reindex
{
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "index_test",
    "version_type": "external"
  }
}
若在索引index_test中,已經存在版本號爲1的文檔1,而在索引gaoyh中同樣存在版本號爲1的文檔1,則會造成版本衝突,響應結果如下:
{
  "took": 33,
  "timed_out": false,
  "total": 5,
  "updated": 0,
  "created": 4,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 1,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": [
    {
      "index": "index_test",
      "type": "test",
      "id": "1",
      "cause": {
        "type": "version_conflict_engine_exception",
        "reason": "[test][1]: version conflict, current version [1] is higher or equal to the one provided [1]",
        "index_uuid": "Qqk6nvQMQFGE6tw3Xb-PGw",
        "shard": "0",
        "index": "index_test"
      },
      "status": 409
    }
  ]
}
即文檔1沒法從索引gaoyh中複製到索引index_test中;

若索引gaoyh中的文檔1的版本號比索引index_test中文檔1的版本號高,則會更新索引index_test中的文檔1(響應結果如下),此時文檔1的版本號等同索引gaoyh中文檔1的版本號:
{
  "took": 4,
  "timed_out": false,
  "total": 5,
  "updated": 5,
  "created": 0,
  "deleted": 0,
  "batches": 1,
  "version_conflicts": 0,
  "noops": 0,
  "retries": {
    "bulk": 0,
    "search": 0
  },
  "throttled_millis": 0,
  "requests_per_second": -1,
  "throttled_until_millis": 0,
  "failures": []
}
設置op_type爲create會導致_reindex在目標指數只會造成文件丟失。所有現有文檔都會導致版本衝突,即只能複製目標索引index_test中沒有的文檔,已有的文檔,都不能從gaoyh中複製過來:
POST _reindex
{
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "index_test",
    "op_type": "create"
  }
}
默認情況下,版本衝突會中止該_reindex過程,但您可以通過"conflicts": "proceed"請求正文中的設置對它們進行計數:
POST _reindex
{
  "conflicts": "proceed", 
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "index_test",
    "op_type": "create"
  }
}
加上"conflicts": "proceed"後響應結果中不會具體顯示failures。
但是,版本衝突時並未造成reindex過程中止。

您可以通過向其添加類型source或通過添加查詢來限制文檔。

如,只複製舊索引twitter中用戶kimchy的文檔到新索引new_twitter中:
POST _reindex
{
  "source": {
    "index": "twitter",
    "type": "_doc",
    "query": {
      "term": {
        "user": "kimchy"
      }
    }
  },
  "dest": {
    "index": "new_twitter"
  }
}
也可以通過設置來限制處理文檔的數量 size。這隻會將單個文檔複製twitter到 new_twitter
POST _reindex
{
  "size": 2, 
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "index_test"
  }
}
設置size爲2,則會隨機從索引gaoyh中選擇2個文檔複製到新索引index_test中(說是隨機,但感覺不是隨機的-_-||試了4次,每次都是gaoyh中的文檔2和5被複制過來。。)

source部分支持搜索請求中支持的所有元素 。例如,可以使用source過濾重新索引原始文檔中的一部分字段,如下所示:
POST _reindex
{
  "source": {
    "index": "twitter",
    "_source": ["user", "_doc"]
  },
  "dest": {
    "index": "new_twitter"
  }
}
像_update_by_query一樣,_reindex也支持腳本修改文檔。與_update_by_query不一樣的是,_reindex允許腳本修改文檔的元數據。e.g.
POST _bulk
{"index":{"_index":"gaoyh","_type":"test","_id":"1"}}
{"user":"aaa","content":"test"}
{"index":{"_index":"gaoyh","_type":"test","_id":"2"}}
{"user":"aaa","content":"test"}
{"index":{"_index":"gaoyh","_type":"test","_id":"3"}}
{"user":"ccc","content":"test"}
{"index":{"_index":"gaoyh","_type":"test","_id":"4"}}
{"user":"bbb","content":"test"}
{"index":{"_index":"gaoyh","_type":"test","_id":"5"}}
{"user":"bbb","content":"test"}

PUT index_test
{
  "settings":{
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "test":{
      "properties": {
        "user":{
          "type": "text"
        },
        "content":{
          "type": "text"
        }
      }
    }
  }
}

POST _reindex
{
  "source": {
    "index": "gaoyh"
  },
  "dest": {
    "index": "index_test",
    "version_type": "external"
  },
  "script": {
    "source":"if(ctx._source.user=='aaa'){ctx._version++;ctx._source.remove('user')}",
    "lang": "painless"
  }
}

GET index_test/test/_mget
{ "ids":["1","2","3","4","5"] }

響應結果如下:
{
  "docs": [
    {
      "_index": "index_test",
      "_type": "test",
      "_id": "1",
      "_version": 2,
      "found": true,
      "_source": {
        "content": "test"
      }
    },
    {
      "_index": "index_test",
      "_type": "test",
      "_id": "2",
      "_version": 2,
      "found": true,
      "_source": {
        "content": "test"
      }
    },
    {
      "_index": "index_test",
      "_type": "test",
      "_id": "3",
      "_version": 1,
      "found": true,
      "_source": {
        "user": "ccc",
        "content": "test"
      }
    },
    {
      "_index": "index_test",
      "_type": "test",
      "_id": "4",
      "_version": 1,
      "found": true,
      "_source": {
        "user": "bbb",
        "content": "test"
      }
    },
    {
      "_index": "index_test",
      "_type": "test",
      "_id": "5",
      "_version": 1,
      "found": true,
      "_source": {
        "user": "bbb",
        "content": "test"
      }
    }
  ]
}
即:索引gaoyh中user爲aaa的文檔被腳本刪除user字段後並增加版本號後複製到新索引index_test中,索引gaoyh中的文檔內容不變。

小結:
與_update_by_query一樣,你可以通過設置 ctx.op 更改在目標索引上執行的操作:
  • noop
設置 ctx.op = "noop" ,則符合腳本內容的文檔將不會被編入目標索引(即不會複製到新索引中);響應結果中會在響應正文(response body)中的noop counter中報告出來;
  • delete
設置 ctx.op = "noop" ,則符合腳本內容的文檔會在目標索引中刪除;響應結果中會在響應正文(response body)中的deleted counter中報告出來;
  • 其他
設置 ctx.op爲其他任何內容都將返回錯誤,就像在ctx中設置任何其他字段一樣。

你可以改變:_id , _type , _index , _version , _routing ;

設置 _version 爲 null 或從 ctx 地圖中清除它,相當於發送的索引請求中不包含版本信息,這將導致目標索引中的文檔被覆蓋重寫,不管文檔在目標索引上的版本或您在 _reindex 請求中使用的版本類型如何。(雖然設置 ctx._version=null,但是複製到目標索引中的文檔的版本號和舊索引中原文檔的版本號一樣,不會置零)

默認情況下,如果_reindex查看帶有路由的文檔,則除非腳本更改了路由,否則將保留路由。您可以routing根據 dest請求設置更改此設置:
  • keep
將針對每個匹配發送的批量請求的路由設置爲匹配上的路由。這是默認值;
  • discard
設置爲每個匹配發送的批量請求的路由爲null
  • =<some text>
將針對每個匹配發送的批量請求的路由設置爲=之後的文本。

例如,您可以使用以下請求將source索引中包含公司名稱爲cat的所有文檔複製到路由設置爲cat的索引dest中
POST _reindex
{
  "source": {
    "index": "source",
    "query": {
      "match": {
        "company": "cat"
      }
    }
  },
  "dest": {
    "index": "dest",
    "routing": "=cat"
  }
}
重新索引以更改字段名稱
_reindex可用於構建具有重命名字段的索引副本。

假設您創建一個包含如下所示文檔的索引:
POST test/_doc/1?refresh
{
  "text": "words words",
  "flag": "foo"
}
但你不喜歡這個名字flag,想要用它替換它tag。 _reindex可以爲您創建其他索引:
POST _reindex
{
  "source": {
    "index": "test"
  },
  "dest": {
    "index": "test2"
  },
  "script": {
    "source": "ctx._source.tag = ctx._source.remove(\"flag\")"
  }
}

GET test2/_doc/1

return:

{
  "found": true,
  "_id": "1",
  "_index": "test2",
  "_type": "_doc",
  "_version": 1,
  "_source": {
    "text": "words words",
    "tag": "foo"
  }
}
Reindex from Remote
從遠程索引
Reindex支持從遠程Elasticsearch集羣重建索引:
POST _reindex
{
  "source": {
    "remote": {
      "host": "http://otherhost:9200",
      "username": "user",
      "password": "pass"
    },
    "index": "source",
    "query": {
      "match": {
        "test": "data"
      }
    }
  },
  "dest": {
    "index": "dest"
  }
}
host參數必須包含方案,主機和端口(例如 https://otherhost:9200)。的usernamepassword參數是可選的,並且當它們存在時_reindex將連接到使用基本認證遠程Elasticsearch節點。https使用基本身份驗證時一定要使用,否則密碼將以純文本形式發送。

URL參數
除了標準參數等pretty,重新索引API還支持refreshwait_for_completionwait_for_active_shardstimeout, scrollrequests_per_second

發送refreshurl參數將導致刷新請求所寫的所有索引。這與Index API的refresh 參數不同,後者僅導致接收新數據的分片被刷新。
如果請求包含,wait_for_completion=false則Elasticsearch將執行一些預檢檢查,啓動請求,然後返回task 可與Tasks API 一起使用的取消或獲取任務狀態的請求。Elasticsearch還將創建此任務的記錄作爲文檔.tasks/task/${taskId}。這是你的保留或刪除你認爲合適。完成後,刪除它,以便Elasticsearch可以回收它使用的空間。
wait_for_active_shards控制在繼續重建索引之前必須激活碎片的副本數量。詳情請見此處 。timeout控制每個寫入請求等待不可用分片變爲可用的時間。兩者都完全適用於 Bulk API中的工作方式。由於_reindex採用滾動搜索,你還可以指定scroll參數來控制多長時間保持“搜索上下文”活着,(例如?scroll=10m)。默認值爲5分鐘。

Reindex是使用批處理實現的,任何故障都會導致整個進程中止,但當前批處理中的所有故障都會被收集到數組中。您可以使用該conflicts選項來防止reindex在版本衝突中中止。



切片

重新索引多個索引

Reindex每日指數













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