MongoDB:如何改变字段的types?

在Stackoverflow中有一个问题,与我的问题非常相似。 问题是这个问题的答案是Java驱动程序,我试图在shell中执行。

我正在这样做…

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

这不行!

更改$type数据$type的唯一方法是对数据具有正确types的数据执行更新。

在这种情况下,它看起来像试图将$type从1(double)更改为2(string)。 http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24type

因此,只需从数据库中加载文档,执行转换( new String(x) ),然后再次保存该文档。

如果您需要以编程方式完全从shell执行此操作,则可以使用find(...).forEach(function(x) {})语法。


回应下面的第二条评论。 将字段从数字更改为集合foo的string。

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

将string字段转换为整数:

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

将整数字段转换为string:

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

用于string到int的转换。

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

用于string双重转换。

  obj.my_value= parseInt(obj.my_value); 

对于浮动:

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

要将int32转换为mongo中的string而不创build数组, 只需将“”添加到您的号码 🙂

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

我需要更改集合中多个字段的数据types,所以我使用以下方法在文档集合中进行多个数据types更改。 回答一个老问题,但可能有助于他人。

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

要将stringtypes的字段转换为date字段,您需要使用forEach()方法迭代find()方法返回的游标,在循环内将该字段转换为Date对象,然后使用$set操作员。

利用批量API来批量更新,这样可以提供更好的性能,因为您将批量发送操作到服务器1000,这样可以提供更好的性能,因为您不会将每个请求发送到服务器,只需要一次1000个请求。

以下演示了这种方法,第一个示例使用MongoDB版本中可用的Bulk API >= 2.6 and < 3.2 。 它通过将所有created_at字段更改为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(); } 

下一个示例适用于新的MongoDB版本3.2 ,该版本已经弃用了批量API,并使用bulkWrite()提供了一组更新的apis:

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

试试这个查询

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

真正帮助我在MondoDB中更改对象的types正是这条简单的线条,可能在这里提到…:

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

用户是我的集合,年龄是有一个string,而不是一个整数(int32)的对象。

我在mongodb控制台中使用这个脚本进行string浮动转换…

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

而这一个在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) ); } 

演示更改types的字段从string到mongo objectId使用mongoose

“`的JavaScript

  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就是这样的风格的另一个例子

数字,string,布尔值,希望答案会帮助别人。