如何在 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" }}}]
)