小数类型不是 JavaScript 原生的,因此 shell 中的 NumberDecimal 值是表示存储在 MongoDB 中的 BSON 值的特殊包装器。如果你想使用parseFloat()
您可以将 NumberDecimal 转换为 JSON 以访问字符串值。例如,在您的原始代码中,这将是:parseFloat(x.test.toJSON()["$numberDecimal"])
.
然而,更好的方法是使用聚合框架来操作十进制值,包括算术运算 (MongoDB 3.4+) 和类型转换 (MongoDB 4.0+)。
MongoDB 4.0+ 包括$toDouble()表达 https://docs.mongodb.com/manual/reference/operator/aggregation/toDouble/它将把数值(十进制、整数、长整型、布尔值、日期、字符串)转换为双精度值。 MongoDB 4.0 中的聚合框架不能用于更新文档(除非您想创建新集合或使用以下方式替换现有集合)$out https://docs.mongodb.com/manual/reference/operator/aggregation/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 版本)添加了对使用某些更新的聚合阶段 https://docs.mongodb.com/master/reference/method/db.collection.update/#update-with-an-aggregation-pipeline,所以在4.2中上述更新可以更简洁地表示为:
db.collection.updateMany(
{ test: { $exists: true }},
[ { $addFields: { testDouble: { $toDouble: "$test" }}}]
)