How to change the type of a field?

后端 未结 13 2045
北荒
北荒 2020-11-22 15:10

I am trying to change the type of a field from within the mongo shell.

I am doing this...

db.meta.update(
  {\'fields.properties.default\': { $type :         


        
相关标签:
13条回答
  • 2020-11-22 15:14
    db.coll.find().forEach(function(data) {
        db.coll.update({_id:data._id},{$set:{myfield:parseInt(data.myfield)}});
    })
    
    0 讨论(0)
  • 2020-11-22 15:14

    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.

    0 讨论(0)
  • 2020-11-22 15:15

    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',
             },
          ]);
    
    0 讨论(0)
  • 2020-11-22 15:20

    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)
        );
    
    
    }
    
    0 讨论(0)
  • 2020-11-22 15:25

    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);
    });
    
    0 讨论(0)
  • 2020-11-22 15:27

    Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update of a field based on its own value:

    // { a: "45", b: "x" }
    // { a:  53,  b: "y" }
    db.collection.update(
      { a : { $type: 1 } },
      [{ $set: { a: { $toString: "$a" } } }],
      { multi: true }
    )
    // { a: "45", b: "x" }
    // { a: "53", b: "y" }
    
    • The first part { a : { $type: 1 } } is the match query:

      • It filters which documents to update.
      • In this case, since we want to convert "a" to string when its value is a double, this matches elements for which "a" is of type 1 (double)).
      • This table provides the codes representing the different possible types.
    • The second part [{ $set: { a: { $toString: "$a" } } }] is the update aggregation pipeline:

      • Note the squared brackets signifying that this update query uses an aggregation pipeline.
      • $set is a new aggregation operator (Mongo 4.2) which in this case modifies a field.
      • This can be simply read as "$set" the value of "a" to "$a" converted "$toString".
      • What's really new here, is being able in Mongo 4.2 to reference the document itself when updating it: the new value for "a" is based on the existing value of "$a".
      • Also note "$toString" which is a new aggregation operator introduced in Mongo 4.0.
    • Don't forget { multi: true }, otherwise only the first matching document will be updated.


    In case your cast isn't from double to string, you have the choice between different conversion operators introduced in Mongo 4.0 such as $toBool, $toInt, ...

    And if there isn't a dedicated converter for your targeted type, you can replace { $toString: "$a" } with a $convert operation: { $convert: { input: "$a", to: 2 } } where the value for to can be found in this table:

    db.collection.update(
      { a : { $type: 1 } },
      [{ $set: { a: { $convert: { input: "$a", to: 2 } } } }],
      { multi: true }
    )
    
    0 讨论(0)
提交回复
热议问题