如何实现类似于 db.collection.find().limit(10)
的功能,但同时更新文档呢?
我目前使用的方法非常糟糕,即先使用 db.collection.find().limit()
获取文档,再进行更新。
总体上来说,我想要返回给定数量的记录,并更改每个记录中的一个字段。
谢谢。
如何实现类似于 db.collection.find().limit(10)
的功能,但同时更新文档呢?
我目前使用的方法非常糟糕,即先使用 db.collection.find().limit()
获取文档,再进行更新。
总体上来说,我想要返回给定数量的记录,并更改每个记录中的一个字段。
谢谢。
您可以使用:
db.collection.find().limit(NUMBER_OF_ITEMS_YOU_WANT_TO_UPDATE).forEach(
function (e) {
e.fieldToChange = "blah";
....
db.collection.save(e);
}
);
(forEach 代码由 MongoDB:使用来自同一文档的数据更新文档提供)
这将只更改指定数量的条目。例如,如果您想将名为“newField”的字段和值1添加到“collection”中的一半条目,可以输入:
db.collection.find().limit(db.collection.count() / 2).forEach(
function (e) {
e.newField = 1;
db.collection.save(e);
}
);
如果您想让另一半也有值为2的"newField",则可以使用更新操作,并设置条件为 newField 不存在:db.collection.update( { newField : { $exists : false } }, { $set : { newField : 2 } }, {multi : true} );
使用forEach
逐个更新每个文档的速度较慢。您可以使用批量方式更新文档。
ids = db.collection.find(<condition>).limit(<limit>).map(
function(doc) {
return doc._id;
}
);
db.collection.updateMany({_id: {$in: ids}}, <update>})
$in
一次检索所有对象,然后同时更新它们更加高效。ids = People.where(firstname: 'Pablo').limit(10000).only(:_id).to_a.map(&:id)
People.in(_id: ids).update_all(lastname: 'Cantero')
查询使用的是 Mongoid 来编写,但也可以很容易地在 Mongo Shell 中重写。
很不幸,据我所知,你拥有的解决方法是唯一的方法。有一个布尔标志multi
,当为true
时将更新所有匹配项,否则将只更新第一个匹配项。
正如答案所述,目前还没有办法将要更新(或删除)的文档数量限制为大于1的值。一个解决方法是使用类似以下的方式:
db.collection.find(<condition>).limit(<limit>).forEach(function(doc){db.collection.update({_id:doc._id},{<your update>})})
我最近也需要类似的东西。我认为查询一长串_id然后在$in中进行更新可能也很慢,所以我尝试使用聚合+合并。
while (true) {
const record = db.records.findOne({ isArchived: false }, {_id: 1})
if (!record) {
print("No more records")
break
}
db.records.aggregate([
{ $match: { isArchived: false } },
{ $limit: 100 },
{
$project: {
_id: 1,
isArchived: {
$literal: true
},
updatedAt: {
$literal: new Date()
}
}
},
{
$merge: {
into: "records",
on: "_id",
whenMatched: "merge"
}
}
])
print("Done update")
}
但是如果使用$in进行批量更新比这种方法更好或更差,请随意发表评论。
let fetchStandby = await db.model.distinct("key",{});
fetchStandby = fetchStandby.slice(0, no_of_docs_to_be_updated)
let fetch = await db.model.updateMany({
key: { $in: fetchStandby }
}, {
$set:{"qc.status": "pending"}
})
let batchSize= 10;
for (let i = 0; i <= 1000000; i += batchSize) {
db.collection.update({$and :[{"_id": {$lte: i+batchSize}}, {"_id": {$gt: i}}]}),{<your update>})
}