在MongoDB中,如何根据领导者的属性整理团队

在MongoDB中,如何根据领导者的属性整理团队,mongodb,join,aggregate,Mongodb,Join,Aggregate,我有一个数据库,其中有一些属于团队的用户。每个队都有一名队长。每个用户都有一个主题 我想按领导的主题整理团队 我的数据如下所示: db={ "teams": [ { _id: "t1", members: [ { "_id": "u1", "leader": true }, { "_id": "u2" }, {

我有一个数据库,其中有一些属于团队的用户。每个队都有一名队长。每个用户都有一个主题

我想按领导的主题整理团队

我的数据如下所示:

db={
  "teams": [
    {
      _id: "t1",
      members: [
        {
          "_id": "u1",
          "leader": true
        },
        {
          "_id": "u2"
        },
        {
          "_id": "u3"
        }
      ],
    },
    {
      _id: "t2",
      members: [
        {
          "_id": "u2",
          "leader": true
        },
        {
          "_id": "u4"
        }
      ],

    },
    {
      _id: "t3",
      members: [
        {
          "_id": "u1",
          "leader": true
        },
        {
          "_id": "u4"
        }
      ],

    },
    {
      _id: "t4",
      members: [
        {
          "_id": "u2",
          "leader": true
        }
      ],

    },

  ],
  "users": [
    {
      "_id": "u1",
      "subject": "history"
    },
    {
      "_id": "u2",
      "subject": "maths"
    },
    {
      "_id": "u3",
      "subject": "geography"
    },
    {
      "_id": "u4",
      "subject": "french"
    }
  ]
}
我想要的结果是:

{
    "history": ["t1", "t3"],
    "maths": ["t2", "t4"]
}
我有一个聚合,可以得到每个领导者的id,从那里我可以分阶段得到我想要的结果,首先找到每个领导者的主题,然后回顾各个项目,根据领导者的身份为每个项目分配一个主题。这是可行的,但它并不雅致,我认为它会很慢。在我看来,应该有更好的方法来做到这一点,也许是加入

有没有一种巧妙的方法可以从单个MongoDB操作中获得我想要的结果

这是一个Mongo游乐场,有我的数据:

非常感谢你的帮助


编辑:我的测试数据令人困惑,因为两个集合中都使用了“\u id”,因此很难解开答案。这是一个更新版本,它为每个集合使用了不同的键名,帮助我理解了完美的答案。

是的,您应该在
用户上加入您的集合。_id
使用
$lookup
,然后使用
$arrayToObject
将值转换为键(在Mongodb 3.4.4中介绍)

以下是一种可能的方法:

db.teams.aggregate([
  {
    "$unwind": "$members"
  },
  {
    "$match": {
      "members.leader": true
    }
  },
  {
    "$lookup": {
      "from": "users",
      "localField": "members._id",
      "foreignField": "_id",
      "as": "users"
    }
  },
  {
    "$unwind": "$users"
  },
  {
    "$group": {
      "_id": "$users.subject",
      "team": {
        "$push": "$_id"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$arrayToObject": [
          [
            {
              k: "$_id",
              v: "$team"
            }
          ]
        ]
      }
    }
  }
])

在线试用:

是的,您应该加入
用户上的集合。_id
使用
$lookup
,然后使用
$arrayToObject
将值转换为键(在Mongodb 3.4.4中介绍)

以下是一种可能的方法:

db.teams.aggregate([
  {
    "$unwind": "$members"
  },
  {
    "$match": {
      "members.leader": true
    }
  },
  {
    "$lookup": {
      "from": "users",
      "localField": "members._id",
      "foreignField": "_id",
      "as": "users"
    }
  },
  {
    "$unwind": "$users"
  },
  {
    "$group": {
      "_id": "$users.subject",
      "team": {
        "$push": "$_id"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$arrayToObject": [
          [
            {
              k: "$_id",
              v: "$team"
            }
          ]
        ]
      }
    }
  }
])
在线试用: