在MongoDB中如何按领导者的财产整理团队

时间:2019-06-25 09:07:23

标签: mongodb join aggregate

我有一个数据库,其中包含一些属于团队的用户。每个团队都有一个领导者。每个用户都有一个主题。

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

我的数据如下:

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游乐场:

https://mongoplayground.net/p/SIJv9-hVNzJ

非常感谢您的帮助。

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

1 个答案:

答案 0 :(得分:0)

是的,您应该在users._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"
            }
          ]
        ]
      }
    }
  }
])

在线试用:mongoplayground.net/p/TuEpMzHkI-0