遇到 Elasticsearch 無法進行數值運算的問題嗎?本篇教學將指導你如何透過 Reindex 和 Mapping 設定,快速修正欄位類型錯誤。
前言
在進行網路流量分析時,我需要統計 Fortinet 防火牆的 bytesin 和 bytesout 數據。然而,在嘗試進行加總計算時發現,這些欄位被儲存為文字(text)格式,導致無法直接進行數值運算。為了解決這個問題,需要將這些欄位的資料類型從文字改為長整數(long)。
問題分析
當 Elasticsearch 自動推斷欄位類型時,有時會將數值資料判定為文字類型。這種情況下,即使欄位內容都是數字,也無法進行數值計算,例如:
- 無法計算總和(sum)
- 無法計算平均值(average)
- 無法進行數值比較
解決方案
解決這個問題需要經過以下幾個步驟:
建立新的 Index Template
首先,需要建立一個新的 index template,確保未來新建立的索引會使用正確的欄位類型:
PUT /_index_template/logstash-arc-fortinet-template
{
"index_patterns": ["logstash-arc-fortinet*"],
"template": {
"mappings": {
"properties": {
"bytesin": {
"type": "long"
},
"bytesout": {
"type": "long"
}
}
}
}
}
建立臨時索引
建立一個暫時的索引來存放轉換後的資料:
PUT /temp_fortinet_index
{
"mappings": {
"properties": {
"bytesin": {
"type": "long"
},
"bytesout": {
"type": "long"
}
}
}
}
第一次 Reindex
將原始資料重新索引到臨時索引:
POST /_reindex?wait_for_completion=false
{
"source": {
"index": "logstash-arc-fortinet*",
"size": 1000
},
"dest": {
"index": "temp_fortinet_index"
}
}
這裡使用 wait_for_completion=false
參數來非同步執行,並返回一個任務 ID。
監控 Reindex 進度
使用返回的任務 ID 來查看進度:
GET /_tasks/{task_id}
建立新的目標索引
當第一次 reindex 完成後,建立最終的目標索引:
PUT /logstash-arc-fortinet-000001
{
"aliases": {
"logstash-arc-fortinet": {}
}
}
第二次 Reindex
將資料從臨時索引移至最終索引:
POST /_reindex?wait_for_completion=false
{
"source": {
"index": "temp_fortinet_index",
"size": 1000
},
"dest": {
"index": "logstash-arc-fortinet-000001"
}
}
清理工作
當確認所有資料都正確轉移後,刪除臨時索引:
DELETE /temp_fortinet_index
注意事項
- 備份資料:在進行任何索引操作前,確保有資料備份
- 磁碟空間:需要確保有足夠的磁碟空間進行 reindex 操作
- 監控進度:對於大量資料,reindex 可能需要較長時間,要定期監控進度
- 驗證資料:完成後要檢查新索引中的資料是否完整和正確
- 效能影響:大型 reindex 操作可能會影響叢集效能,建議在非尖峰時段執行
驗證方式
完成所有步驟後,可以透過以下方式驗證:
- 在 Kibana 的 Discover 頁面確認資料可以正常瀏覽
- 檢查欄位的 mapping 是否正確設置為 long 類型
- 嘗試進行數值計算(如 sum, avg 等)確認功能正常
結論
使用 Elasticsearch Reindex 可有效解決資料無法正確加總的問題,透過調整 Elasticsearch Mapping,我們可以確保 bytesin 和 bytesout 欄位正確轉換為 long 類型,使得可以進行正確的數值統計和分析。雖然過程較為複雜,但遵循正確的步驟,可以安全地完成資料轉換,且確保未來的資料都會使用正確的欄位類型。
這個解決方案不僅適用於 Fortinet 日誌分析,也可應用於其他類似的欄位類型轉換需求。記住要注意磁碟空間管理和效能影響,選擇適當的時機執行轉換操作。