我有一个集合t1
,其架构中包含以下字段
_id, field1, field1
我希望设置field2
的值field1
,如sql:
update t1 set field1=field2;
我如何在MongoDB中执行此操作?
答案 0 :(得分:37)
这里有好消息和坏消息。
坏消息是AFAIK你不能通过单个update()调用来做 - mongo不支持在更新中引用当前对象。
好消息是还有其他方法可以做到这一点,例如:你可以运行forEach循环:
db.item.find(conditions...).forEach( function (doc) {
doc.field1 = doc.field2;
db.item.save(doc);
});
您可以在admin shell('mongo'命令)中运行forEach,或者通过特定驱动程序的某些方法运行(例如在PHP中我希望它可以与mongodb.execute()一起使用,如下所述: http://www.php.net/manual/en/mongodb.execute.php)
答案 1 :(得分:11)
从版本3.4开始,我们可以使用public class UseCase
{
public string UseCaseId { get; set; }
public string UseCaseDescription { get; set; }
}
public class RootObject
{
public List<UseCase> UseCases { get; set; }
}
聚合管道运算符,而无需客户端处理,这是最有效的方法。
$addFields
在版本3.4之前,我们需要迭代db.collection.aggregate(
[
{ "$addFields": { "field2": "$field1" }},
{ "$out": "collection" }
]
)
对象并使用$set
运算符添加具有现有“field1”值的新字段。您需要使用“批量”操作来实现此目的,以实现最高效率。
MongoDB 3.2弃用Bulk()
及其associated methods,因此从3.2开始,您需要使用bulkWrite
方法。
Cursor
从版本2.6到3.0,您可以使用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);
}
API。
Bulk
答案 2 :(得分:2)
这可以通过以下方式完成:
db.nameOfCollection.find().forEach(
function (elem) {
db.nameOfCollection.update(
{
_id: elem._id
},
{
$set: {
field2: elem.field1
}
}
);
}
);