最近有一個需求舷胜,需要修改ES文檔中的金額叁扫,以前是以元
為單位枕扫,現(xiàn)在要換算成以萬元
為單位陪腌,但并不是所有數(shù)據(jù)都需要做處理,有一個Excel存儲著不需要處理的數(shù)據(jù)。我第一時間想到的就是用Python
寫一個腳本處理ES文檔诗鸭,噼里啪啦一頓操作之后商叹,基本就實現(xiàn)了該功能。但是處理的結果并不是預期的那樣只泼。下面我簡單的舉一個例子來復現(xiàn)一下我所遇到的問題剖笙。
首先,創(chuàng)建一個索引test
,
# 創(chuàng)建test索引
PUT test
給索引設置mapping屬性请唱,
# 設置索引mapping屬性
PUT test/_mapping
{
"properties": {
"id": {"type": "keyword"},
"money": {"type": "double"}
}
}
給索引添加幾條測試文檔數(shù)據(jù)弥咪,
# 批量插入數(shù)據(jù)
POST _bulk
{"index": {"_index": "test"}}
{"id":"1", "money": 23423123}
{"index": {"_index": "test"}}
{"id":"2","money": 1233656}
{"index": {"_index": "test"}}
{"id":"3", "money":899234}
既然要更新文檔數(shù)據(jù),肯定要用到ES的_update_by_query
API十绑。我們現(xiàn)在將每個文檔的money
值除以10000
聚至,先自己考慮一下應該會得到一個什么樣的結果。
# 更新操作本橙,將每個文檔的money除以10000
POST test/_update_by_query
{
"script": {
"source": "ctx._source.money=ctx._source.money/10000",
"lang": "painless"
},
"query": {
"match_all": {}
}
}
有結果了嗎扳躬?我們來看看ES給我們處理后的結果是啥樣的,
# 查看文檔
GET test/_search
# 結果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "_doc",
"_id" : "LtrDs3MBvTJiRW6OWDLQ",
"_score" : 1.0,
"_source" : {
"money" : 2342,
"id" : "1"
}
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "MNrDs3MBvTJiRW6OYTJx",
"_score" : 1.0,
"_source" : {
"money" : 123,
"id" : "2"
}
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "MtrDs3MBvTJiRW6OaTLM",
"_score" : 1.0,
"_source" : {
"money" : 89,
"id" : "3"
}
}
]
}
}
很明顯更新后的結果去掉了小數(shù)點后面的數(shù)甚亭,這并不是我想要的贷币。這是怎么回事呢?經過查找很多的資料亏狰,最終在官方文檔里找到這么一句話:
Use the
division operator '/'
to DIVIDE one numeric type value by another. Rules for NaN values and division by zero follow the JVM specification. Division with integer values drops the remainder of the resultant value.
最后一句話的意思很明了役纹,“整數(shù)相除會丟棄結果值的余數(shù)部分”。既然整數(shù)會有這種情況暇唾,那么我將10000
換成10000.0
再來試試促脉,
# 更新操作,將每個文檔的money除以10000.0
POST test/_update_by_query
{
"script": {
"source": "ctx._source.money=ctx._source.money/10000.0",
"lang": "painless"
},
"query": {
"match_all": {}
}
}
這次的更新結果如下策州,
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "_doc",
"_id" : "Ptq5s3MBvTJiRW6OoTEW",
"_score" : 1.0,
"_source" : {
"money" : 2342.3123,
"id" : "1"
}
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "QNq5s3MBvTJiRW6OpzFr",
"_score" : 1.0,
"_source" : {
"money" : 123.3656,
"id" : "2"
}
},
{
"_index" : "test",
"_type" : "_doc",
"_id" : "Qdq5s3MBvTJiRW6OrjEB",
"_score" : 1.0,
"_source" : {
"money" : 89.9234,
"id" : "3"
}
}
]
}
}
這才是想要的結果瘸味。從整體的實現(xiàn)來看,雖然功能很簡單够挂,但是一些細節(jié)的地方處理不到位旁仿,很可能就耽誤你很多的時間。用這時間來摸魚下硕,它不香嗎丁逝。
注:Elasticsearch版本是7.8.0汁胆,以上操作都是通過kibana
執(zhí)行的梭姓。
相關鏈接:https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-operators-numeric.html
獲取最新文章,可關注博客地址:https://jenkinwang.github.io/嫩码,或掃碼關注微信公眾號:一只慵懶的程序猿
誉尖。