MongoDB: Comment changer le type d’un champ?

Il y a déjà une question dans Stackoverflow, très similaire à ma question. Le fait est que la réponse à cette question était pour un pilote Java, j’essaie de le faire dans le shell.

Je fais ça …

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

Cela ne fonctionne pas!

La seule façon de modifier le $type des données consiste à effectuer une mise à jour sur les données dont le type est correct.

Dans ce cas, il semble que vous essayiez de changer le $type de 1 (double) à 2 (chaîne) .

Il vous suffit donc de charger le document à partir de la firebase database, d’effectuer la conversion ( new Ssortingng(x) ), puis de sauvegarder à nouveau le document.

Si vous devez faire cela entièrement à partir du shell, vous pouvez utiliser la syntaxe find(...).forEach(function(x) {}) .


En réponse au deuxième commentaire ci-dessous. Remplacez le champ d’un numéro par une chaîne de la collection foo .

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

Convertir le champ Ssortingng en 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); }); 

Convertir un champ entier en chaîne:

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

Pour chaîne à convertir en int.

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

Pour chaîne à double conversion.

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

Pour float:

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

Ce qui m’a vraiment aidé à changer le type d’object dans MondoDB, c’était juste cette simple ligne, peut-être mentionnée ici …:

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

Les utilisateurs sont ma collection et age est l’object qui avait une chaîne au lieu d’un entier (int32).

Pour convertir int32 en chaîne dans mongo sans créer de tableau, ajoutez simplement “” à votre numéro 🙂

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

Pour convertir un champ de type chaîne en champ date, vous devez itérer le curseur renvoyé par la méthode find() à l’aide de la méthode forEach() , dans la boucle, convertir le champ en object Date, puis mettre à jour le champ en utilisant $set opérateur.

Tirez parti de l’utilisation de l’ API en bloc pour les mises à jour en bloc qui offrent de meilleures performances car vous enverrez les opérations au serveur par lots de 1000, ce qui vous donnera de meilleures performances car vous n’envoyez pas toutes les requêtes au serveur 1000 demandes.

L’exemple suivant illustre cette approche. Le premier exemple utilise l’API en bloc disponible dans les versions MongoDB >= 2.6 and < 3.2 . Il met à jour tous les documents de la collection en changeant tous les champs created_at champs de date:

 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(); } 

L'exemple suivant s'applique à la nouvelle version 3.2 MongoDB qui a depuis déconseillé l'API en bulkWrite() et fourni un nouvel ensemble d' bulkWrite() utilisant 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 }); 

Je dois modifier le type de données de plusieurs champs de la collection. J’ai donc utilisé les éléments suivants pour modifier plusieurs types de données dans la collection de documents. Répondre à une ancienne question mais peut être utile pour les autres.

 db.mycoll.find().forEach(function(obj) { if (obj.hasOwnProperty('phone')) { obj.phone = "" + obj.phone; // int or longint to ssortingng } if (obj.hasOwnProperty('field-name')) { obj.field-name = new NumberInt(obj.field-name); //ssortingng to integer } if (obj.hasOwnProperty('cdate')) { obj.cdate = new ISODate(obj.cdate); //ssortingng to Date } db.mycoll.save(obj); }); 
 You can easily convert the ssortingng data type to numerical data type. Don't forget to change collectionName & FieldName. for ex : CollectionNmae : Users & FieldName : Contactno. 

Essayez cette requête ..

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

J’utilise ce script dans la console mongodb pour que les chaînes puissent flotter les 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); } ); 

Et celui-ci en 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) ); } 

démo changer le type de champ mid de ssortingng en mongo objectId en utilisant 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 est juste un autre exemple de styles tels que

Nombre, chaîne, booléen qui espèrent que la réponse aidera quelqu’un d’autre.

Jusqu’à présent, toutes les réponses utilisent une version de forEach, itérant sur tous les éléments de la collection côté client.

Cependant, vous pouvez utiliser le traitement côté serveur de MongoDB en utilisant le pipeline d’agrégat et l’ étape de sortie $ comme:

l’étape $ out remplace de manière atomique la collection existante par la nouvelle collection de résultats.

Exemple:

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