简体   繁体   English

加入/查找mongoose模式的agregation

[英]Join/lookup agregation on mongoose schema

I'm currently making an achievement system and trying to save it in two collections. 我目前正在制作一个成就系统并尝试将其保存在两个系列中。 One collection that contains the name and id, and the other collections with users and their progress. 一个包含名称和ID的集合,以及包含用户及其进度的其他集合。

I've been looking at Aggregation, and on $lookup, and made some progress, but I'm not sure what would be necessary to do to make the desired output that I would like. 我一直在关注聚合,在$ lookup上,并取得了一些进展,但我不确定要做出我想要的所需输出是什么。

If the user exists in achievements, get the progress value and their userid with the collection, if not, make progress value to 0. 如果用户存在于成就中,则使用集合获取进度值及其用户ID,否则,将进度值设为0。

Wouldnt this be some kind of joining in for example Mysql?, how would this be in MongoDB? 难道这不是一种加入例如Mysql ?,这在MongoDB中会怎样?

variable userid = 33; 变量userid = 33;

attempt: 尝试:

db.getCollection('achievements').aggregate([
   {
     $lookup:
       {
         from: "achievement_users",
         localField: "id",
         foreignField: "id",
         as: "inventory_docs"
       }
  }
])

achievement schema: 成就模式:

{
    "name" : "testing",
    "id" : 1,
    "max" : 12,
},

{
    "name" : "testing2",
    "id" : 2,
    "max" : 12,

}

achievement user: 成就用户:

{
    "userid" : 33,
    "id" : 1,
    progress: 1,
},
 {
        "userid" : 446,
        "id" : 1,
        progress: 1,
    }

Desired output: 期望的输出:

{
name: "testing",
id: 1,
userid: 33,
progress: 1,
    max : 12,

},
{
name: "testing2",
id: 2,
progress: 0,
    max : 12,

},

EDIT: 编辑:

I need all achievements that the user have done, and not have done ( not have done = progress = 0). 我需要用户所做的所有成就,而不是已经完成(没有完成= progress = 0)。

it may be achievements that the user havent done. 它可能是用户没有完成的成就。 i want them listed too, but to have the progress value of 0. 我也希望它们列出,但是进度值为0。

update 2: Also need it to give me results while there are no match in achievement_users for that spesific userid. 更新2:还需要它给我结果,而achievement_users中没有匹配的特定用户ID。

Here is a solution if you want to perform something similar to LEFT JOIN : 如果你想执行类似LEFT JOIN这是一个解决方案:

db.test.aggregate([{
    $lookup: {
        from: "user",
        localField: "id",
        foreignField: "id",
        as: "inventory_docs"
    }
}, {
    $unwind: {path: "$inventory_docs", preserveNullAndEmptyArrays: true }
}, {
    $addFields: {
        userid: "$inventory_docs.userid",
        progress: {$cond: {if: "$inventory_docs.progress", then: "$inventory_docs.progress", else: 0 }},
    }
}, {
    $project: {
        inventory_docs: 0
    }
}])

$lookup create an array from the joined collection $lookup从连接的集合中创建一个数组

$unwind split the array in records $unwind将数组拆分为记录

$addFields extract the field you want as you want $addFields提取所需的字段

$cond replace an empty progress with 0 $cond用0替换空进度

$project for a final clean up $project进行最后清理

You can use below aggregation 您可以使用以下聚合

db.achievement_users.aggregate([
  { "$match": { "userid": 33 }},
  { "$lookup": {
    "from": "achievement",
    "let": { "id": "$id", "progress": "$progress", "userid": "$userid" },
    "pipeline": [
      { "$addFields": {
        "progress": { "$cond": [{ "$eq": ["$id", "$$id"] }, "$$progress", 0] },
        "userid": "$$userid"
      }}
    ],
    "as": "inventory_docs"
  }},
  { "$unwind": "$inventory_docs" },
  { "$replaceRoot": { "newRoot": "$inventory_docs" }}
])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM