MongoDB: How to change the type of a field?

2018-12-31 19:09发布

问题:

There is a question already in Stackoverflow, very similar with my question. The thing is that the answer for that questions was for a Java Driver, I am trying to do it in the shell.

I am doing this...

db.meta.update({\'fields.properties.default\': { $type : 1 }}, {\'fields.properties.default\': { $type : 2 }})

This is not working!

回答1:

The only way to change the $type of the data is to perform an update on the data where the data has the correct type.

In this case, it looks like you\'re trying to change the $type from 1 (double) to 2 (string).

So simply load the document from the DB, perform the cast (new String(x)) and then save the document again.

If you need to do this programmatically and entirely from the shell, you can use the find(...).forEach(function(x) {}) syntax.


In response to the second comment below. Change the field bad from a number to a string in collection foo.

db.foo.find( { \'bad\' : { $type : 1 } } ).forEach( function (x) {   
  x.bad = new String(x.bad); // convert field to string
  db.foo.save(x);
});


回答2:

Convert String field to Integer:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) { 
    obj.field-name = new NumberInt(obj.field-name);
    db.db-name.save(obj);
});

Convert Integer field to String:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
    obj.field-name = \"\" + obj.field-name;
    db.db-name.save(obj);
});


回答3:

For string to int conversion.

db.my_collection.find().forEach( function(obj) {
    obj.my_value= new NumberInt(obj.my_value);
    db.my_collection.save(obj);
});

For string to double conversion.

    obj.my_value= parseInt(obj.my_value, 10);

For float:

    obj.my_value= parseFloat(obj.my_value);


回答4:

db.coll.find().forEach(function(data) {
    db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
})


回答5:

To convert int32 to string in mongo without creating an array just add \"\" to your number :-)

db.foo.find( { \'mynum\' : { $type : 16 } } ).forEach( function (x) {   
  x.mynum = x.mynum + \"\"; // convert int32 to string
  db.foo.save(x);
});


回答6:

What really helped me to change the type of the object in MondoDB was just this simple line, perhaps mentioned before here...:

db.Users.find({age: {$exists: true}}).forEach(function(obj) {
    obj.age = new NumberInt(obj.age);
    db.Users.save(obj);
});

Users are my collection and age is the object which had a string instead of an integer (int32).



回答7:

To convert a field of string type to date field, you would need to iterate the cursor returned by the find() method using the forEach() method, within the loop convert the field to a Date object and then update the field using the $set operator.

Take advantage of using the Bulk API for bulk updates which offer better performance as you will be sending the operations to the server in batches of say 1000 which gives you a better performance as you are not sending every request to the server, just once in every 1000 requests.

The following demonstrates this approach, the first example uses the Bulk API available in MongoDB versions >= 2.6 and < 3.2. It updates all the documents in the collection by changing all the created_at fields to date fields:

var bulk = db.collection.initializeUnorderedBulkOp(),
    counter = 0;

db.collection.find({\"created_at\": {\"$exists\": true, \"$type\": 2 }}).forEach(function (doc) {
    var newDate = new Date(doc.created_at);
    bulk.find({ \"_id\": doc._id }).updateOne({ 
        \"$set\": { \"created_at\": newDate}
    });

    counter++;
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }

The next example applies to the new MongoDB version 3.2 which has since deprecated the Bulk API and provided a newer set of apis using bulkWrite():

var bulkOps = [];

db.collection.find({\"created_at\": {\"$exists\": true, \"$type\": 2 }}).forEach(function (doc) { 
    var newDate = new Date(doc.created_at);
    bulkOps.push(         
        { 
            \"updateOne\": { 
                \"filter\": { \"_id\": doc._id } ,              
                \"update\": { \"$set\": { \"created_at\": newDate } } 
            }         
        }           
    );     
})

db.collection.bulkWrite(bulkOps, { \"ordered\": true });


回答8:

all answers so far use some version of forEach, iterating over all collection elements client-side.

However, you could use MongoDB\'s server-side processing by using aggregate pipeline and $out stage as :

the $out stage atomically replaces the existing collection with the new results collection.

example:

db.documents.aggregate([
         {
            $project: {
               _id: 1,
               numberField: { $substr: [\'$numberField\', 0, -1] },
               otherField: 1,
               differentField: 1,
               anotherfield: 1,
               needolistAllFieldsHere: 1
            },
         },
         {
            $out: \'documents\',
         },
      ]);


回答9:

I need to change datatype of multiple fields in the collection, so I used the following to make multiple data type changes in the collection of documents. Answer to an old question but may be helpful for others.

db.mycoll.find().forEach(function(obj) { 

    if (obj.hasOwnProperty(\'phone\')) {
        obj.phone = \"\" + obj.phone;  // int or longint to string
    }

    if (obj.hasOwnProperty(\'field-name\')) {
     obj.field-name = new NumberInt(obj.field-name); //string to integer
    }

    if (obj.hasOwnProperty(\'cdate\')) {
        obj.cdate = new ISODate(obj.cdate); //string to Date
    }

    db.mycoll.save(obj); 
});


回答10:

You can easily convert the string data type to numerical data type.
Don\'t forget to change collectionName & FieldName.
for ex : CollectionNmae : Users & FieldName : Contactno.

Try this query..

db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});


回答11:

I use this script in mongodb console for string to float conversions...

db.documents.find({ \'fwtweaeeba\' : {$exists : true}}).forEach( function(obj) { 
        obj.fwtweaeeba = parseFloat( obj.fwtweaeeba ); 
        db.documents.save(obj); } );    

db.documents.find({ \'versions.0.content.fwtweaeeba\' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[0].content.fwtweaeeba = parseFloat( obj.versions[0].content.fwtweaeeba ); 
        db.documents.save(obj); } );

db.documents.find({ \'versions.1.content.fwtweaeeba\' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[1].content.fwtweaeeba = parseFloat( obj.versions[1].content.fwtweaeeba );  
        db.documents.save(obj); } );

db.documents.find({ \'versions.2.content.fwtweaeeba\' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[2].content.fwtweaeeba = parseFloat( obj.versions[2].content.fwtweaeeba );  
        db.documents.save(obj); } );

And this one in php)))

foreach($db->documents->find(array(\"type\" => \"chair\")) as $document){
    $db->documents->update(
        array(\'_id\' => $document[_id]),
        array(
            \'$set\' => array(
                \'versions.0.content.axdducvoxb\' => (float)$document[\'versions\'][0][\'content\'][\'axdducvoxb\'],
                \'versions.1.content.axdducvoxb\' => (float)$document[\'versions\'][1][\'content\'][\'axdducvoxb\'],
                \'versions.2.content.axdducvoxb\' => (float)$document[\'versions\'][2][\'content\'][\'axdducvoxb\'],
                \'axdducvoxb\' => (float)$document[\'axdducvoxb\']
            )
        ),
        array(\'$multi\' => true)
    );


}


回答12:

demo change type of field mid from string to mongo objectId using mongoose

 Post.find({}, {mid: 1,_id:1}).exec(function (err, doc) {
             doc.map((item, key) => {
                Post.findByIdAndUpdate({_id:item._id},{$set:{mid: mongoose.Types.ObjectId(item.mid)}}).exec((err,res)=>{
                    if(err) throw err;
                    reply(res);
                });
            });
        });

Mongo ObjectId is just another example of such styles as

Number, string, boolean that hope the answer will help someone else.



标签: mongodb