[英]How to do update multiple docs based on a query in one round trip in MongoDB?
Imagine you have a collection with documents as follows:假设您有一个文档集合,如下所示:
{
"_id": "SOME_MONGO_ID",
"rank": 1
}
And given an _id want to update increment all the documents with rank higher than it.给定一个 _id 想要更新所有排名高于它的文档。
If I know the rank I can use UpdateMany to increment the ranks higher than it using a filter.如果我知道排名,我可以使用 UpdateMany 来增加比使用过滤器更高的排名。 However that would require two round trips one to get the rank and another to do the update many.然而,这将需要两次往返,一次获得排名,另一次进行多次更新。
Is it possible to use a pipeline to lookup the rank and then do the update in one round trip?是否可以使用管道查找排名,然后在一次往返中进行更新?
I'm using the c# mongodb driver.我正在使用 c# mongodb 驱动程序。
This needs to work inside a transaction so we can't use '$merge'这需要在事务内部工作,所以我们不能使用“$merge”
You can use $lookup
with $merge
.您可以将$lookup
与$merge
一起使用。 If you expect few and small documents to return, you can use '$match' first, but it has the disadvantage of temporarily putting all of these updated docs in one document:如果你希望返回的文档很少而且很小,你可以先使用'$match',但它的缺点是暂时将所有这些更新的文档放在一个文档中:
db.collection.aggregate([
{$match: {_id: "SOME_MONGO_ID"}},
{$lookup: {
from: "collection",
as: "updated",
let: {thRank: "$rank"},
pipeline: [{$match: {$expr: {$gt: ["$rank", "$$thRank"]}}}]
}
},
{$unwind: "$updated"},
{$replaceRoot: {newRoot: "$updated"}},
{$project: {rank: {$add: ["$rank", incVal]}}},
{$merge: {into: "collection"}}
])
See how it works on the playground example在playground 示例中查看它是如何工作的
If you expect many documents (or large ones) to return, you can use $lookup
first:如果您希望返回很多文档(或大文档),您可以先使用$lookup
:
db.collection.aggregate([
{$lookup: {
from: "collection",
as: "ref_id",
let: {doc_id: ObjectId("62fb40acd762c3e1150e0134")},
pipeline: [{$match: {$expr: {$eq: ["$_id", "$$doc_id"]}}}]
}
},
{$match: {$expr: {$gt: ["$rank", {$first: "$ref_id.rank"}]}}},
{$unset: "ref_id"},
{$project: {rank: {$add: ["$rank", incVal]}}},
{$merge: {into: "collection"}}
])
See how it works on the playground example - many docs看看它是如何在playground 示例上工作的——许多文档
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.