我尝试使用聚合和查找,但看起来我无法将
role
保留在 members
项中。知道如何解决吗?
db.groups.insertMany([
{
title: 'Hi',
members: [
{
userId: ObjectId('62589515f239750e7e44b958'),
role: 'Admin'
},
{
userId: ObjectId('655f634c632d0c23b9d455de'),
role: 'Member'
}
]
}
])
和
db.users.insertMany([
{
_id: ObjectId('62589515f239750e7e44b958'),
name: 'A',
},
{
_id: ObjectId('655f634c632d0c23b9d455de'),
name: 'B',
}
])
如何使用聚合才能得到这样的结果,非常感谢:
{
title: 'Hi',
members: [
{
user: {
_id: ObjectId('62589515f239750e7e44b958'),
name: 'A',
},
role: 'Admin'
},
{
user: {
_id: ObjectId('655f634c632d0c23b9d455de'),
name: 'B',
},
role: 'Member'
},
]
}
$unwind
成员们表演$lookup
。稍微调整一下物体,然后 $group
改造物体。
db.groups.aggregate([
{
"$unwind": "$members"
},
{
"$lookup": {
"from": "users",
"localField": "members.userId",
"foreignField": "_id",
"as": "usersLookup"
}
},
{
"$unwind": "$usersLookup"
},
{
"$set": {
"members": {
"user": "$usersLookup",
"role": "$members.role"
}
}
},
{
"$group": {
"_id": "$_id",
"title": {
$first: "$title"
},
"members": {
"$push": "$members"
}
}
}
])
查找的问题是,如果将新字段插入到现有数组中,它将替换该数组,而不是将结果添加到数组中的每个对象。 Mongo 文档提供了一个类似的 示例,其中包含
$lookup
和 $mergeObjects
。在您的情况下有效使用它的关键是首先$unwind
members
。最后,展开(倒带?卷起?)对象并将 members.user
添加到单个数组中。
db.groups.aggregate([
{
"$unwind": "$members"
},
{
"$lookup": {
"from": "users",
"localField": "members.userId",
"foreignField": "_id",
"as": "members.user"
}
},
{
// convert list of one user to just user object
"$set": {
"members.user": {
"$arrayElemAt": [
"$members.user",
0
]
}
}
},
{
// your example output doesn't have this field
"$unset": "members.userId"
},
{
// un-unwind / rewind / windup
"$group": {
"_id": "$_id",
"members": {
"$push": "$members"
},
// add all remaining fields
"title": {
"$first": "$title"
}
}
}
])
对于好奇的人来说,这与 Ray 的答案 之间的区别在于我查找的是
members
对象而不是根级别。如果成员的每个对象中有许多字段,则此管道不需要 set
设置其他每个字段。