mongoose 如何在mongodb中查找子数组?

mbzjlibv  于 12个月前  发布在  Go
关注(0)|答案(2)|浏览(189)

我试图使用聚合和查找,但看起来像我不能保持rolemembers项目。任何想法如何解决它?

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',
    }
])


我们如何通过使用aggregate来得到这样的结果,非常感谢:

{
    title: 'Hi',
    members: [
        {
            user: {
                _id: ObjectId('62589515f239750e7e44b958'), 
                name: 'A',
            },
            role: 'Admin'
        },
        {
            user: {
                _id: ObjectId('655f634c632d0c23b9d455de'), 
                name: 'B',
            },
            role: 'Member'
        },
    ]
}

bvk5enib

bvk5enib1#

$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 Playground

alen0pnh

alen0pnh2#

查找的问题是,如果你将新字段插入到一个现有数组中,它会替换该数组,而不是将结果添加到数组中的每个对象。Mongo文档提供了一个类似的$lookup$mergeObjects的示例。在您的情况下有效使用它的关键是先$unwindmembers。最后,取消展开(rewind?windup?)对象并将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"
      }
    }
  }
])

字符串
Mongo Playground
PS.需要一个更优雅的解决方案来选择最终$group中的所有“其他”字段。现在,“title”是唯一的一个,所以它很好,但可能带有$project的东西会更好地适用于这些情况。
对于好奇的人来说,这和Ray's answer之间的区别是我查找到members对象而不是在根级别。如果每个成员对象中有许多字段,那么这个管道不需要set查找其他每个字段。

相关问题