MongoDB: ¿Cómo cambiar el tipo de un campo?

Ya hay una pregunta en Stackoverflow, muy similar a mi pregunta. La cuestión es que la respuesta para esas preguntas fue para un controlador de Java, estoy tratando de hacerlo en el shell.

Yo estoy haciendo esto…

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

¡Esto no está funcionando!

La única forma de cambiar el $type de $type de los datos es realizar una actualización de los datos donde los datos tienen el tipo correcto.

En este caso, parece que está intentando cambiar el $type de 1 (doble) a 2 (cadena) .

Así que simplemente cargue el documento desde el DB, realice el molde ( new String(x) ) y luego guarde el documento nuevamente.

Si necesita hacer esto programáticamente y completamente desde el shell, puede usar la syntax find(...).forEach(function(x) {}) .


En respuesta al segundo comentario a continuación. Cambia el campo bad de un número a una cadena en la colección foo .

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

Convertir campo de cadena en entero:

 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 el campo Entero en Cadena:

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

Para la conversión de cadena a int.

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

Para cadena a doble conversión.

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

Para flotar:

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

Lo que realmente me ayudó a cambiar el tipo de objeto en MondoDB fue esta simple línea, tal vez mencionada antes aquí …

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

Los usuarios son mi colección y la edad es el objeto que tenía una cadena en lugar de un número entero (int32).

Para convertir int32 en una cadena en mongo sin crear una matriz solo agrega “” a tu número 🙂

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

Para convertir un campo del tipo de cadena en campo de fecha, necesitaría iterar el cursor devuelto por el método find() utilizando el método forEach() , dentro del ciclo convertir el campo a un objeto Date y luego actualizar el campo usando $set operador.

Aproveche el uso de la API Bulk para actualizaciones masivas que ofrecen un mejor rendimiento, ya que enviará las operaciones al servidor en lotes de, por ejemplo, 1000, que le ofrece un mejor rendimiento ya que no está enviando cada solicitud al servidor, solo una vez cada 1000 solicitudes.

Lo siguiente demuestra este enfoque, el primer ejemplo usa la API Bulk disponible en las versiones de MongoDB >= 2.6 and < 3.2 . Actualiza todos los documentos de la colección al cambiar todos los campos created_at campos de fecha:

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

El siguiente ejemplo se aplica a la nueva versión 3.2 MongoDB, que desde entonces ha bulkWrite() utilizar la API Bulk y ha proporcionado un conjunto más nuevo de apis mediante 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 }); 

Necesito cambiar el tipo de datos de varios campos en la colección, así que usé lo siguiente para hacer cambios múltiples en el tipo de datos en la colección de documentos. Responda a una pregunta anterior pero puede ser útil para otros.

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

Prueba esta consulta …

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

Utilizo este script en la consola de mongodb para las conversiones de cadena a flotante …

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

Y este 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) ); } 

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 es solo otro ejemplo de estilos como

Number, string, boolean que esperan que la respuesta ayude a alguien más.

todas las respuestas hasta ahora usan alguna versión de forEach, iterando sobre todos los elementos de colección del lado del cliente.

Sin embargo, podría usar el procesamiento del lado del servidor de MongoDB al usar la canalización agregada y la etapa $ out como:

la etapa $ out reemplaza atómicamente la colección existente con la nueva colección de resultados.

ejemplo:

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