如何在Node.js/Mongoose中将Decimal128转换为Float类型
将MongoDB Decimal128类型的orderAmount转换为浮点数
问题场景
使用Orders.find()从MongoDB查询文档时,orderAmount字段返回的是Decimal128类型,示例返回结果:
{ _id: new ObjectId('6672a038a102620d14a93cac'), userId: 6458, orderId: 106733, orderAmount: new Decimal128('134.25'), orderStatus: 100, orderDate: 2024-06-19T09:09:12.246Z, processed: false, __v: 0 }
对应的Mongoose Schema定义:
const OrderSchema = new mongoose.Schema({ userId: { type: Number, }, orderId: { type: Number, }, orderAmount: { type: mongoose.Types.Decimal128, }, orderStatus: { type: Number, }, orderDate: { type: Date, default: Date.now, }, processed: { type: Boolean, default: false, }, });
需要将orderAmount转换为浮点数,预期结果:
{ _id: new ObjectId('6672a038a102620d14a93cac'), userId: 6458, orderId: 106733, orderAmount: 134.25, orderStatus: 100, orderDate: 2024-06-19T09:09:12.246Z, processed: false, __v: 0 }
解决方案
方法1:Schema中添加Getter(推荐)
在Schema的orderAmount字段定义getter函数,实现查询时自动转换:
const OrderSchema = new mongoose.Schema({ userId: { type: Number }, orderId: { type: Number }, orderAmount: { type: mongoose.Types.Decimal128, // 转换Decimal128为浮点数,处理null/undefined情况 get: (val) => val ? parseFloat(val.toString()) : null }, orderStatus: { type: Number }, orderDate: { type: Date, default: Date.now }, processed: { type: Boolean, default: false }, }); // 确保toJSON/toObject输出时getter生效 OrderSchema.set('toJSON', { getters: true }); OrderSchema.set('toObject', { getters: true });
此方法一劳永逸,所有查询都会自动转换orderAmount类型。
方法2:查询结果手动转换
若不想修改Schema,可在查询后遍历结果手动处理:
Orders.find().then(orders => { const transformedOrders = orders.map(order => { const orderObj = order.toObject(); orderObj.orderAmount = orderObj.orderAmount ? parseFloat(orderObj.orderAmount.toString()) : null; return orderObj; }); // 使用转换后的transformedOrders });
方法3:聚合管道转换
利用MongoDB聚合管道的$toDouble操作符,在查询阶段直接转换:
Orders.aggregate([ { $addFields: { orderAmount: { $toDouble: '$orderAmount' } } } ]).then(orders => { // 返回的orders中orderAmount已为浮点数 });
内容的提问来源于stack exchange,提问作者DXB-DEV
相关产品推荐
相关产品推荐

