如何在 MongoDB shell 中将 NumberDecimal 转换为 Double?
How to convert NumberDecimal to Double in MongoDB shell?
我有一份文件 "test" 归档为 NumberDecimal
类型
{ "_id" : ObjectId("5d1a202e476381c30cd995a4"), "test" : NumberDecimal("0.1") }
如何将 "test" 字段从 NumberDecimal
转换为 mongodb shell 中的 Double
?
我试过执行
db.collection.find({"test": {$exists: true}}).forEach(function (x) { x.test = parseFloat(x.test); db.collection.save(x); });
但不要解决这个问题,因为它 return NaN
小数类型不是 JavaScript 的原生类型,因此 shell 中的 NumberDecimal 值是表示存储在 MongoDB 中的 BSON 值的特殊包装器。如果要使用 parseFloat()
,可以将 NumberDecimal 转换为 JSON 以访问字符串值。例如,在您的原始代码中,这将是:parseFloat(x.test.toJSON()["$numberDecimal"])
.
但是,更好的方法是使用聚合框架来操作十进制值,包括算术运算(MongoDB 3.4+)和类型转换(MongoDB 4.0+)。
MongoDB 4.0+ 包含 $toDouble()
expression that will convert numeric values (decimal, int, long, boolean, date, string) to a double. The aggregation framework in MongoDB 4.0 cannot be used to update documents (unless you want to create a new collection or replace the existing collection using $out
),因此您必须 运行 聚合查询来转换值,然后单独应用文档更新:
// Find matching documents
var docs = db.collection.aggregate([
{ $match: {
test: { $exists: true }
}},
// Add a new field converting the decimal to a double
// (alternatively, the original "test" value could also be replaced)
{ $addFields: {
testDouble: { $toDouble: "$test" }
}}
])
// Update with the changes (Note: this could be a bulk update for efficiency)
docs.forEach(function (doc) {
db.collection.update({ _id: doc._id}, {$set: { testDouble: doc.testDouble }});
});
// Check the results
> db.collection.find().limit(1)
{
"_id" : ObjectId("5d1a202e476381c30cd995a4"),
"test" : NumberDecimal("0.1"),
"testDouble" : 0.1
}
MongoDB 4.2(目前在RC中)增加了对使用一些aggregation stages for updates的支持,所以在4.2上面的更新可以更简洁的表述为:
db.collection.updateMany(
{ test: { $exists: true }},
[ { $addFields: { testDouble: { $toDouble: "$test" }}}]
)
我有一份文件 "test" 归档为 NumberDecimal
类型
{ "_id" : ObjectId("5d1a202e476381c30cd995a4"), "test" : NumberDecimal("0.1") }
如何将 "test" 字段从 NumberDecimal
转换为 mongodb shell 中的 Double
?
我试过执行
db.collection.find({"test": {$exists: true}}).forEach(function (x) { x.test = parseFloat(x.test); db.collection.save(x); });
但不要解决这个问题,因为它 return NaN
小数类型不是 JavaScript 的原生类型,因此 shell 中的 NumberDecimal 值是表示存储在 MongoDB 中的 BSON 值的特殊包装器。如果要使用 parseFloat()
,可以将 NumberDecimal 转换为 JSON 以访问字符串值。例如,在您的原始代码中,这将是:parseFloat(x.test.toJSON()["$numberDecimal"])
.
但是,更好的方法是使用聚合框架来操作十进制值,包括算术运算(MongoDB 3.4+)和类型转换(MongoDB 4.0+)。
MongoDB 4.0+ 包含 $toDouble()
expression that will convert numeric values (decimal, int, long, boolean, date, string) to a double. The aggregation framework in MongoDB 4.0 cannot be used to update documents (unless you want to create a new collection or replace the existing collection using $out
),因此您必须 运行 聚合查询来转换值,然后单独应用文档更新:
// Find matching documents
var docs = db.collection.aggregate([
{ $match: {
test: { $exists: true }
}},
// Add a new field converting the decimal to a double
// (alternatively, the original "test" value could also be replaced)
{ $addFields: {
testDouble: { $toDouble: "$test" }
}}
])
// Update with the changes (Note: this could be a bulk update for efficiency)
docs.forEach(function (doc) {
db.collection.update({ _id: doc._id}, {$set: { testDouble: doc.testDouble }});
});
// Check the results
> db.collection.find().limit(1)
{
"_id" : ObjectId("5d1a202e476381c30cd995a4"),
"test" : NumberDecimal("0.1"),
"testDouble" : 0.1
}
MongoDB 4.2(目前在RC中)增加了对使用一些aggregation stages for updates的支持,所以在4.2上面的更新可以更简洁的表述为:
db.collection.updateMany(
{ test: { $exists: true }},
[ { $addFields: { testDouble: { $toDouble: "$test" }}}]
)