我想將 ElasticSearch 映射屬性從 更改text為ip,但它們是不兼容的型別。
我知道公認的答案是:
- 創建具有正確映射的新索引;
- 運行
_reindexAPI 以復制資料; - 煮一杯咖啡;
- 洗掉原索引;
- 創建從原始索引到新索引的別名。
但是,我正在處理363GB 索引中的50 億條記錄,每天可能有數十萬條新記錄寫入其中。上述程序在洗掉舊索引和創建新別名的程序中至少會涉及一些停機時間,并且在重新索引完成和下一步之間的時間里會丟失記錄。(并且重建索引程序將花費數小時,如果不是幾天的話。)就地進行轉換會更好,也許創建一個新欄位并復制舊索引?有任何想法嗎?
uj5u.com熱心網友回復:
實際上比這容易得多。程序如下:
A. 修改您的映射以將ip子欄位添加到現有欄位,例如
PUT index/_mapping
{
"properties": {
"your_ip_field": {
"type": "text",
"fields": {
"ip": {
"type": "ip"
}
}
}
}
}
B. 呼叫index/_update_by_query?wait_for_completion=false&slices=auto你的索引
C. 這里什么都沒有,僅此而已。
呼叫_update_by_query將簡單地獲取每個_source檔案并對其自身重新編制索引(即新版本),然后ip子欄位將可用于您的查詢。
每天寫入索引的所有新檔案都將使用新映射,而舊映射將在更新呼叫期間更新。不需要別名切換,也不需要重新索引。
更新完成后,您將能夠參考your_ip_field.ip欄位欄位以使用ip它的版本。
這樣做的缺點是your_ip_field你的倒排索引中仍然會有標記化的文本,你可能不需要,但你不能擁有它。有更復雜的解決方案可以使它正確,但是這個很簡單,可以讓你開始。
uj5u.com熱心網友回復:
事實上,重新索引這么大的索引不是一個好主意,我建議創建一個新欄位并使用攝取管道將其映射到新欄位并在應用程式端進行更改以獲得正確的資料型別。(您可以使用 update_byQuery添加新欄位)
另一種選擇是使用運行時欄位(在ES 7.11中引入),在這種情況下,您的決議將從索引時間切換到查詢時間。
關于重新索引,您可以通過使用讀取和寫入別名在 ES 中實作零停機時間重新索引以獲取更多資訊,請查看此處。
uj5u.com熱心網友回復:
感謝@Kaveh,我使用了攝取管道/update_by_query 解決方案。
我會將解決方案描述為任何正在尋找它的人的答案。
0. 我正在將名為“user_ip”的關鍵字欄位轉換為“my_index”上名為“ip_addr”的 IP 欄位。
您可以通過 Kibana 完成大部分此類作業,但我將使用 ElasticSearch 開發工具控制臺樣式,因此您可以根據需要在其中運行所有內容。
1. 創建攝取管道
根據這些說明,這對 Kibana 來說很簡單。攝取管道名為ip_transform. 如果你想將它作為代碼運行,它看起來如下:
PUT _ingest/pipeline/ip_transform
{
"processors": [
{
"convert": {
"field": "user_ip",
"type": "ip",
"target_field": "ip_addr",
"ignore_missing": true
}
}
]
}
2.在索引中創建欄位
PUT my_index/_mapping
{
"properties": {
"ip_addr": {
"type": "ip"
}
}
}
3.將此設定為該索引的默認管道
這不是絕對必要的,您可以添加?pipeline=ip_transform到您的呼叫中,但我不想更改我的代碼,我總是想運行這個管道。
PUT my_index/_settings
{
"index.default_pipeline": "ip_transform"
}
4. 在現有記錄上運行管道
我們使用_update_by_query API針對每個現有記錄運行管道。
POST my_index/_update_by_query?pipeline=ip_transform&wait_for_completion=false
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "ip_addr"
}
}
}
}
}
對于大資料集,這將需要一段時間,但您可以獲取回傳的 ID 并查詢它是否完整:
GET _tasks/<Job ID>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/464129.html
上一篇:彈性搜索分析API回應并出現錯誤
