我有一个集合t1
,其架构中有以下字段
_id, field1, field1
我想要 setfield2
的值field1
,如 sql:
update t1 set field1=field2;
我如何在 MongoDB 中做到这一点?
我有一个集合t1
,其架构中有以下字段
_id, field1, field1
我想要 setfield2
的值field1
,如 sql:
update t1 set field1=field2;
我如何在 MongoDB 中做到这一点?
这里有好消息和坏消息。
坏消息是 AFAIK 你不能用一个 update() 调用来做到这一点 - mongo 不支持在更新中引用当前对象。
好消息是还有其他方法可以做到这一点,例如你可以运行一个 forEach 循环:
db.item.find(conditions...).snapshot().forEach( function (doc) {
doc.field1 = doc.field2;
db.item.save(doc);
});
您可以在管理外壳('mongo' 命令)中运行 forEach,或者通过特定驱动程序的某些方法(例如,在 PHP 中,我希望它可以与 mongodb.execute() 一起使用,如下所述:http:/ /www.php.net/manual/en/mongodb.execute.php )
从 3.4 版本开始,我们可以使用$addFields
聚合管道操作符,无需客户端处理,这是最有效的方式。
db.collection.aggregate(
[
{ "$addFields": { "field2": "$field1" }},
{ "$out": "collection" }
]
)
在 3.4 版本之前,我们需要迭代Cursor
对象并使用$set
运算符添加具有现有“field1”值的新字段。您需要使用“批量”操作来实现最高效率。
MongoDB 3.2 弃用Bulk()
及其相关方法,因此从 3.2 开始,您需要使用该bulkWrite
方法。
var requests = [];
db.collection.find({}, { 'field1': 1 } ).snapshot().forEach(document => {
requests.push( {
'updateOne': {
'filter': { '_id': document._id },
'update': { '$set': { 'field2': document.field1 } }
}
});
if (requests.length === 1000) {
//Execute per 1000 operations and re-init
db.collection.bulkWrite(requests);
requests = [];
}
});
if(requests.length > 0) {
db.collection.bulkWrite(requests);
}
从版本 2.6 到 3.0,您可以使用Bulk
API。
var bulk = db.collection.initializeUnorderedBulOp();
var count = 0;
db.collection.find({}, { 'field1': 1 }).snapshot().forEach(function(document) {
bulk.find({ '_id': document._id }).updateOne( {
'$set': { 'field2': document.field1 }
});
count++;
if(count%1000 === 0) {
// Excecute per 1000 operations and re-init
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
}
})
// clean up queues
if(count > 0) {
bulk.execute();
}
这可以通过以下方式完成:
db.nameOfCollection.find().forEach(
function (elem) {
db.nameOfCollection.update(
{
_id: elem._id
},
{
$set: {
field2: elem.field1
}
}
);
}
);