MongoDB convert string type to float type

HaBo picture HaBo · Jun 21, 2016 · Viewed 10.8k times · Source

Following the suggestions over here MongoDB: How to change the type of a field? I tried to update my collection to change the type of field and its value.

Here is the update query

db.MyCollection.find({"ProjectID" : 44, "Cost": {$exists: true}}).forEach(function(doc){
    if(doc.Cost.length > 0){
        var newCost = doc.Cost.replace(/,/g, '').replace(/\$/g, '');
        doc.Cost =  parseFloat(newCost).toFixed(2);  
        db.MyCollection.save(doc);
        } // End of If Condition
    }) // End of foreach

upon completion of the above query, when I run the following command

db.MyCollection.find({"ProjectID" : 44},{Cost:1})

I still have Cost field as string.

{
    "_id" : ObjectId("576919b66bab3bfcb9ff0915"),
    "Cost" : "11531.23"
}

/* 7 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0916"),
    "Cost" : "13900.64"
}

/* 8 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0917"),
    "Cost" : "15000.86"
}

What am I doing wrong here?

Here is the sample document

/* 2 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0911"),
    "Cost" : "$7,100.00"
}

/* 3 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0912"),
    "Cost" : "$14,500.00"
}

/* 4 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0913"),
    "Cost" : "$12,619.00"
}

/* 5 */
{
    "_id" : ObjectId("576919b66bab3bfcb9ff0914"),
    "Cost" : "$9,250.00"
}

Answer

Enrique Fueyo picture Enrique Fueyo · Jun 21, 2016

The problem is that toFixed returns an String, not a Number. Then your are just updating the document with a new, and different String.

Example from Mongo Shell:

> number = 2.3431
2.3431
> number.toFixed(2)
2.34
> typeof number.toFixed(2)
string

If you want a 2 decimals number you must parse it again with something like:

db.MyCollection.find({"ProjectID" : 44, "Cost": {$exists: true}}).forEach(function(doc){
  if(doc.Cost.length > 0){
    var newCost = doc.Cost.replace(/,/g, '').replace(/\$/g, '');
    var costString = parseFloat(newCost).toFixed(2);
    doc.Cost = parseFloat(costString);
    db.MyCollection.save(doc);
  } // End of If Condition
}) // End of foreach