如何在 Mongoose/MongoDB 中聚合两个集合?

Max*_*ich 3 mongoose mongodb node.js aggregation-framework

在我的学习服务器上。我有两个关于用户及其种族的集合。Races 具有userId属性,以便了解哪些用户发起了这场比赛。我需要整合所有用户和所有种族的对象。

我有用户集合:

[
    {
        "_id": "5d938ec8b17e522018e327db",
        "name": "max",
        "surname": "buinevich",
        "username": "axe",
        "__v": 0
    }
]
Run Code Online (Sandbox Code Playgroud)

和比赛集合:

[
    {
        "_id": "5d93ac4c7076dc212ce187d6",
        "userId": "5d938ec8b17e522018e327db",
        "stageId": "5d939e16d4e51d2eac81827d",
        "title": "test race",
        "time": 33,
        "description": "test desc",
        "__v": 0
    }
]
Run Code Online (Sandbox Code Playgroud)

所以我需要让所有用户参加适当的比赛才能得到如下结果:

[
    {
        "_id": "5d938ec8b17e522018e327db",
        "name": "max",
        "surname": "buinevich",
        "username": "axe",
        "races": [{
                    "_id": "5d93ac4c7076dc212ce187d6",
                    "userId": "5d938ec8b17e522018e327db",
                    "stageId": "5d939e16d4e51d2eac81827d",
                    "title": "test race",
                    "time": 33,
                    "description": "test desc",
                    "__v": 0
                }]
        "__v": 0
    }
]
Run Code Online (Sandbox Code Playgroud)

我不想在集合模式中使用引用。也许是猫鼬聚合之类的东西。

amb*_*ing 8

如果不使用refsin mongoose schemas(尽管推荐),因为populate生成分层文档非常方便。

选项是使用本机聚合管道, $lookup该管道本质上对连接的集合执行(类似于 SQL 中的 LEFT JOIN)以填充数组字段中的文档。

聚合查询:

db.usersCollection.aggregate([
  {
    $lookup: {
      from: "racesCollection",
      localField: "_id",
      foreignField: "userId",
      as: "races"
    }
  }
]).pretty();
Run Code Online (Sandbox Code Playgroud)

Mongoose 模型聚合查询如下所示:

UserModel.aggregate.lookup({
  from: "Races", //or Races.collection.name
  localField: "_id",
  foreignField: "userId",
  as: "races"
});
Run Code Online (Sandbox Code Playgroud)

输出:

{
    "_id" : ObjectId("5d938ec8b17e522018e327db"),
    "name" : "max",
    "surname" : "buinevich",
    "username" : "axe",
    "__v" : 0,
    "races" : [
        {
            "_id" : ObjectId("5d93ac4c7076dc212ce187d6"),
            "userId" : ObjectId("5d938ec8b17e522018e327db"),
            "stageId" : ObjectId("5d939e16d4e51d2eac81827d"),
            "title" : "test race",
            "time" : 33,
            "description" : "test desc",
            "__v" : 0
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)