Decimal128 being read as new Decimal128("#") instead of the number
Problem
Prerequisites - [X] I have written a descriptive issue title Mongoose version 7.4.2 Node.js version 20.2.0 MongoDB version 1.42.1 Operating system macOS Operating system version (i.e. 20.04, 11.3, 10) Sonoma 14.2.1 Issue I'm trying to use a double/float data type for example (rev: 1.2), when I was using Number, mongoose would write it as an int so I've switched to using Decimal128 which would be better for our long term goals but I can't get rid of "new Decimal128". I'm open to whatever will let us use decimals and really would love to keep it simple. For instance rev 1.2 was being written as 1, and now that I've switched to Decimal128 it's reading it from the database (console.log on read) as: [code block] Schema: [code block] Database stores it as: [code block] I've been trying all sorts of different things but I can't manage to get mongoose to read from the MongoDB without the "new Decimal128" part of it. I've tried parseFloat, v.getDecimals and not using getters and setters. Thanks in advance for any help. MongoDB version for MongoDBCompass
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Fix Decimal128 Handling in Mongoose
Mongoose's Decimal128 type is being returned as an instance of the Decimal128 class instead of a primitive number. This occurs because Mongoose is designed to handle Decimal128 as an object to maintain precision, but it needs to be converted to a primitive type for easier use in calculations and display.
Awaiting Verification
Be the first to verify this fix
- 1
Update Mongoose Schema
Ensure that the schema is correctly set up to use Decimal128 for the desired fields. This allows Mongoose to properly handle the data type.
javascriptconst mongoose = require('mongoose'); const Schema = mongoose.Schema; const mySchema = new Schema({ rev: { type: mongoose.Schema.Types.Decimal128 } }); - 2
Convert Decimal128 to Number on Retrieval
When retrieving the data from the database, convert the Decimal128 instance to a primitive number using the toString() method followed by parseFloat(). This will allow you to work with the value as a standard number.
javascriptconst retrievedData = await MyModel.find(); const revAsNumber = parseFloat(retrievedData.rev.toString()); - 3
Implement Getter Method
Optionally, implement a getter method in your schema to automatically convert Decimal128 values to numbers when accessed. This keeps your code clean and reduces repetitive conversion.
javascriptmySchema.virtual('revAsNumber').get(function() { return parseFloat(this.rev.toString()); }); - 4
Test the Changes
Run your application and test the retrieval of the Decimal128 values. Ensure that they are now being returned as primitive numbers without the 'new Decimal128' prefix.
javascriptconsole.log(retrievedData.revAsNumber);
Validation
Confirm that the retrieved values are now displayed as primitive numbers (e.g., 1.2) instead of instances of Decimal128. Check the console output after implementing the above steps.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep