[英]Project nested array element to top level using MongoDB aggregation pipeline
我有一个包含表单文档的groups
集合
{
"_id": "g123"
...,
"invites": [
{
"senderAccountId": "a456",
"recipientAccountId": "a789"
},
...
]
}
我希望能够列出用户收到的所有邀请。
我想在groups
集合上使用聚合管道,过滤所有组以仅返回用户被邀请加入的组。
db.groups.aggregate([
{
$match: {
"invites.recipientAccountID": "<user-id>"
}
}
])
最后我想投影这个组数组以结束形式的数组
[
{
"senderAccountId": "a...",
"recipientAccountId": "<user-id>",
"groupId": "g...", // Equal to "_id" field of document.
},
...
]
但是我在聚合管道中缺少将嵌套的senderAccountId
和recipientAccountId
字段带到顶层的“项目”步骤。 我在 MongoDB 查询和聚合管道中看到了在线投影示例,但我找不到将文档数组字段的先前匹配元素投影到顶级的示例。
我想过使用数组更新运算符来引用匹配的元素,但使用这种方法无法取得任何有意义的进展。
我想你想要的是$replaceRoot
:
db.collection.aggregate([
{$match: {"invites.recipientAccountId": "a789"}},
{$set: {
invites: {$first: {
$filter: {
input: "$invites",
cond: {$eq: ["$$this.recipientAccountId", "a789"]}
}
}}
}},
{$replaceRoot: {newRoot: {$mergeObjects: ["$invites", {group: "$_id"}]}}}
])
在playground 示例中查看它是如何工作的
有多种方法可以做到这一点,结合使用unwind
和project
也可以。 Unwind
将为每个project
创建一个 object,让您选择如何使用当前变量构建结果。
db.collection.aggregate([
{
"$unwind": "$invites"
},
{
"$match": {
"invites.recipientAccountId": "a789"
}
},
{
"$project": {
recipientAccountId: "$invites.recipientAccountId",
senderAccountId: "$invites.senderAccountId",
groupId: "$_id",
_id: 0 // don't show _id key:value
}
}
])
您还可以使用 nimrod serok 的$replaceRoot
代替$project
一个
{$replaceRoot: {newRoot: {$mergeObjects: ["$invites", {group: "$_id"}]}}}
nimrod serok 的解决方案可能会好一点,因为我的先展开它然后再匹配它,但我相信我的更具可读性
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.