请帮忙!,我有两个集合,名为
coll1
和 coll2
。我想根据 coll2
字段更新 coll1
并从 coll2
返回更新的文档
coll1 :[{"_id":"some_unique_id1", "plan":{"type":"premium"}},
{"_id":"some_unique_id2", "plan":{"type":"free"}}]
coll2 :[{"_id":"some_unique_id3", "user_id":"some_unique_id1", "eligible":false}]
如果用户有高级计划,我想在
eligible: true
中设置 coll2
并仅从 coll2
返回更新的文档。
我所做的是更新
coll2
,但没有返回更新后的文档。
这是我的示例代码
let data = await db.collection("coll1").aggregate([
{
$match: {
"plan.type": "premium"
}
},
{
$addFields: {
eligible: true
}
},
{
$project: {
_id: 0, user_id: "$_id", eligible: 1
}
},
{
$merge: {
into: "coll2",
on: ["user_id"],
whenMatched: "merge",
}
}
]).toArray();
console.log(data)
我无法完成这个任务。我怎样才能做到这一点?我可以在
$function
管道中使用 $merge
吗?
我刚刚找到了答案。这不可能。您将不得不再次查询。
https://www.mongodb.com/community/forums/t/is-it-possible-to-merge-and-return/133337
MongoDB 支持团队说:
目前还不可能。如果你只想要结果,就 在 $merge 之前执行聚合管道中的所有阶段 阶段。但如果你想将它输出到另一个集合中 您将需要额外的查询。
欲了解更多详情,请查看上面的链接。
来自MongoDB文档,
如果聚合结果包含基于 on 规范匹配的一个或多个文档,则 $merge 可以替换输出集合中的现有文档。因此,如果聚合结果包含集合中所有现有文档的匹配文档并且您为whenMatched指定“替换”,则 $merge 可以替换现有集合中的所有文档。我认为从这个角度来看,返回的聚合结果应该是预期的,因为它是替换中的“to-be”文档。
对于您的情况,您可以首先 $lookup 整个 coll2 文档,将
eligible
更新为 true。然后执行 $replaceRoot,然后进行最终合并。
db.coll1.aggregate([
{
$match: {
"plan.type": "premium"
}
},
{
"$lookup": {
"from": "coll2",
"localField": "_id",
"foreignField": "user_id",
"as": "coll2Lookup"
}
},
{
"$unwind": "$coll2Lookup"
},
{
$addFields: {
"coll2Lookup.eligible": true
}
},
{
"$replaceRoot": {
"newRoot": "$coll2Lookup"
}
},
{
$merge: {
into: "coll2",
on: [
"_id"
],
whenMatched: "merge"
}
}
])
这里是Mongo游乐场供您参考。