fir*_*x01 28 mongodb mongodb-query
我有一个集合t1,其架构中包含以下字段
_id, field1, field1
Run Code Online (Sandbox Code Playgroud)
我希望set field2的值field1类似于sql:
update t1 set field1=field2;
Run Code Online (Sandbox Code Playgroud)
我如何在MongoDB中执行此操作?
Jak*_* P. 37
这里有好消息和坏消息.
坏消息是AFAIK你不能通过单个update()调用来做 - mongo不支持在更新中引用当前对象.
好消息是还有其他方法可以做到,例如你可以运行forEach循环:
db.item.find(conditions...).forEach( function (doc) {
doc.field1 = doc.field2;
db.item.save(doc);
});
Run Code Online (Sandbox Code Playgroud)
您可以在admin shell('mongo'命令)中运行forEach,或者通过特定驱动程序的某些方法运行(例如在PHP中我希望它可以与mongodb.execute()一起使用,如下所述:http:/ /www.php.net/manual/en/mongodb.execute.php)
sty*_*ane 12
从版本3.4开始,我们可以使用$addFields聚合管道运算符,而无需客户端处理,这是最有效的方法.
db.collection.aggregate(
[
{ "$addFields": { "field2": "$field1" }},
{ "$out": "collection" }
]
)
Run Code Online (Sandbox Code Playgroud)
在版本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);
}
Run Code Online (Sandbox Code Playgroud)
从版本2.6到3.0,您可以使用BulkAPI.
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25406 次 |
| 最近记录: |