首页 > 解决方案 > 即使第一阶段没有结果,mongodb聚合也加入

问题描述

我试图找到一种方法来在下一阶段运行之前伪造一个聚合阶段的成功。

  1. 我正在使用 $match 来过滤用户集合id。这可能没有结果。
  2. 我想使用 $lookup 加入同一个集合上的另一个集合id。即使前一个阶段没有返回结果,这个阶段也应该产生结果。

问题是 $lookup 只有在 $match 产生结果时才会产生结果。

我想我需要在初始 $match 之后使用 $replaceRoot 或 $project ,以便 $lookup 仍然可以引用有效字段。到目前为止,我的尝试在 $lookup 阶段没有显示任何结果。

这是我尝试使用replaceRoot. 当 $match 成功时它实际上成功了,但是当 $match 返回 null 时什么也没有出现。

[{$match: {
  "id": "id-in-users-collection"
}}, {$replaceRoot: {
  newRoot: {$mergeObjects: [
    {"id": "id-fallback"},
    "$$ROOT"
  ]}
}}, {$lookup: {
  from: 'memberships',
  localField: 'id',
  foreignField: 'userId',
  as: 'clubs'
}}]

这是使用 $project 的一次尝试。我确定下面的语法有问题,但是当 $match 产生结果时它实际上会产生结果。

[{$match: {
  "id": "id-in-user-collection"
}}, {$project: {
  "id": {
    $cond: {
      if: "$$ROOT.id",
      then: "$$ROOT.id",
      else: {$literal: {"id": "id-fallback"}}
    }
  }
}}, {$lookup: {
  from: 'memberships',
  localField: 'id',
  foreignField: 'userId',
  as: 'clubs'
}}]

编辑:

假设我在Memberships集合中有这些文件:

{"userId": "1', "clubId": "1", "status": "CREATOR"}
{"userId": "2', "clubId": "1", "status": "PENDING"}

对于用户 id=2,即使User集合中没有文档,我也想执行一个聚合,产生以下结果:

db.users.aggregate(makePipeline(2)).toArray()

想要的:

{
  "id": "2",
  "clubs": [
    {userId: '2', clubId: '1', status: 'PENDING'}
  ]
}

目前,只有在用户集合中添加文档时才能获得所需的结果。

{"id": "2"}

标签: mongodbaggregation-framework

解决方案


推荐阅读