猫鼬模式的加入/查找聚合

时间:2019-03-21 23:24:36

标签: javascript mongodb mongoose aggregation-framework schema

我目前正在制作一个成就系统,并试图将其保存在两个收藏集中。 一个包含名称和ID的集合, 以及其他与用户有关的收藏及其进度。

我一直在查看Aggregation,并在$ lookup上取得了一些进展,但是我不确定要获得所需的输出将需要做什么。

如果用户存在于成就中,则通过集合获取进度值及其用户ID;否则,将进度值设为0。

这不是某种形式的加入,例如Mysql吗?在MongoDB中会如何?

变量userid = 33;

尝试:

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

成就模式:

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

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

}

成就用户:

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

所需的输出:

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

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

},

编辑:

我需要用户已完成但尚未完成的所有成就(未完成=进度= 0)。

这可能是用户尚未完成的成就。我也要列出它们,但进度值为0。

更新2: 还需要它来为我提供结果,而那个特殊用户ID的Achievement_users中没有匹配项。

2 个答案:

答案 0 :(得分:1)

如果您要执行类似于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从加入的集合中创建一个数组

$unwind将数组拆分为记录

$addFields提取所需字段

$cond用0代替空白进度

$project进行最终清理

答案 1 :(得分:1)

您可以使用以下汇总

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" }}
])