按照这里的建议MongoDB: How to change the type of a field?,我尝试更新我的集合以更改字段的类型及其值。
这是更新查询
db.MyCollection.find({"ProjectID" : 44, "Cost": {$exists: true}}).forEach(function(doc){
if(doc.Cost.length > 0){
var newCost = doc.Cost.replace(/,/g, '').replace(/\$/g, '');
doc.Cost = parseFloat(newCost).toFixed(2);
db.MyCollection.save(doc);
} // End of If Condition
}) // End of foreach
在完成上述查询后,当我运行以下命令时
db.MyCollection.find({"ProjectID" : 44},{Cost:1})
我仍然有Cost
字段作为字符串。
{
"_id" : ObjectId("576919b66bab3bfcb9ff0915"),
"Cost" : "11531.23"
}
/* 7 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0916"),
"Cost" : "13900.64"
}
/* 8 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0917"),
"Cost" : "15000.86"
}
我哪里做错了?
以下是示例文档
/* 2 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0911"),
"Cost" : "$7,100.00"
}
/* 3 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0912"),
"Cost" : "$14,500.00"
}
/* 4 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0913"),
"Cost" : "$12,619.00"
}
/* 5 */
{
"_id" : ObjectId("576919b66bab3bfcb9ff0914"),
"Cost" : "$9,250.00"
}
3条答案
按热度按时间2nc8po8w1#
问题是
toFixed
返回的是String
,而不是Number
,那么您只是用一个新的不同的String
更新了文档。来自Mongo Shell的示例:
如果您想要一个2位小数的数字,则必须使用类似以下的语句再次解析它:
zbwhf8kr2#
按照此模式将字符串类型的货币字段转换为浮点型。您需要查询集合中具有Cost字段类型字符串的所有文档。为此,您需要利用**
Bulk API
**进行批量更新。这些方法可以提供更好的性能,因为您将以1000个为一批向服务器发送操作。这样可以提供更好的性能,因为您不是将每个请求都发送到服务器,而是每1000个请求中发送一次。下面演示了这种方法,第一个示例使用MongoDB版本
>= 2.6 and < 3.2
中提供的Bulk API。它通过将所有Cost
字段更改为浮点值字段来更新集合中的所有文档:下一个示例适用于新的MongoDB版本3.2,该版本已经弃用了**
Bulk API
,并使用bulkWrite()
**提供了一组更新的api。它使用与上面相同的游标,但是使用相同的
forEach()
游标方法创建带有批量操作的数组,以将每个批量写入文档推送到数组中。由于写入命令可以接受的操作不超过1000次,因此您需要将操作分组为最多1000次操作,并在循环达到1000次迭代时重新初始化数组:sbdsn5lh3#
从mongoDB版本4.2开始,它可以完全在一个mongoDB查询中使用Updates with Aggregation Pipeline完成:
了解它在playground example上的工作原理