Десятичный тип не является родным для JavaScript, поэтому значения NumberDecimal в оболочке представляют собой специальные оболочки, представляющие значение BSON, хранящееся в MongoDB. Если вы хотите использовать parseFloat()
, вы можете преобразовать NumberDecimal в JSON, чтобы получить доступ к строковому значению. Например, в исходном коде это будет: parseFloat(x.test.toJSON()["$numberDecimal"])
.
Однако лучшим подходом было бы использование структуры агрегации для манипулирования десятичными значениями, включая арифметические операции (MongoDB 3.4+) и преобразование типов (MongoDB 4.0+).
MongoDB 4.0+ включает $toDouble()
выражение , которое преобразует числовые значения (десятичное, целое, длинное, логическое, дату, строку) в двойное число. Платформу агрегации в MongoDB 4.0 нельзя использовать для обновления документов (если только вы не хотите создать новую коллекцию или заменить существующую коллекцию, используя $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) добавляет поддержку использования некоторых этапов агрегации для обновлений , поэтому в 4.2 вышеприведенное обновление может быть более кратко выражено как:
db.collection.updateMany(
{ test: { $exists: true }},
[ { $addFields: { testDouble: { $toDouble: "$test" }}}]
)