Joel Langlois Joel Langlois - 6 months ago 60
Node.js Question

mongodb aggregate $sum returns extra floating point digits

I am looking to sum the price of some inventory items via their skus on my nodejs server. They are floating-point numbers. My documents look like this

[
{
quantity: 1,
price: 38.95,
sku: 'C-2177',
product: 55b9cfc5fa39110bb644becc,
_id: 56739191b98d1fde79c3034e
},
{
quantity: 1,
price: 24.95,
sku: 'C-2188',
product: 55b9d013fa39110bb645100d,
_id: 5743870e139e80b9ecb48e02
}
]


All my prices are defined in my schema as Numbers. When I try the $group $sum operators like this:

InventoryItem.model.aggregate([
{ $match: { 'sku': {$in:['C-2177', 'C-2188']}}},
{ $group: {
_id: null, subtotal:{$sum:'$price'}
}}
], function(err, results){
console.log(results);
});


I get extra floating point digits. Here the sum adds up to $63.90, but I get a response like

[ { _id: null, subtotal: 63.900000000000006 } ]


I'm using mongoose 4.4.2 with the mongodb 2.1.18 driver and my server is running MongoDB 2.6.11. Any help is appreciated!

Answer

These are the normal rounding errors of floats. Try in node:

> var a = 38.95, b = 24.95; console.log(a + b)
63.900000000000006

To avoid that, do not store prices in $, store them in cents. If you have really huge numbers, use a library like bigInteger and store the results as strings.