使用$lookup在mongodb中进行外连接

Ash*_*shh 4 javascript mongoose mongodb node.js aggregation-framework

我有一个频道集合

{
  channel: "Xamper",  //unique
  subscribers: [
    ObjectId("5a934e000102030405000000"),
    ObjectId("5a934e000102030405000001"),
    ObjectId("5a934e000102030405000002")
  ]
}
Run Code Online (Sandbox Code Playgroud)

和一个 用户集合

{
  _id: ObjectId("5a934e000102030405000000"),
  name: "Bradman"
},
{
  _id: ObjectId("5a934e000102030405000001"),
  name: "Hartin"
},
{
  _id: ObjectId("5a934e000102030405000002"),
  name: "Migra"
},
{
  _id: ObjectId("5a934e000102030405000004"),
  name: "Polycor"
}
Run Code Online (Sandbox Code Playgroud)

现在我需要查找频道名称"Xamper"并计算不在subscribers数组中的用户

所以输出将是

{
  channel: "Xamper",
  unSubscribers: 1
}
Run Code Online (Sandbox Code Playgroud)

类似于SQL的外排除连接

在此输入图像描述

use*_*814 5

您可以在 3.6 中使用以下管道。

$lookup使用管道将 Channels 集合加入订阅者的 Users 集合

$count用于将订阅者与 Users 集合中的每个 id 进行比较,并输出匹配文档的数量。$not $in

$project投影输出字段。

db.Channels.aggregate([
  { "$lookup":  {
    "from": "Users",
    "let": { "subscribers": "$subscribers" },
    "pipeline": [
      { "$match": { "$expr": { "$not": { "$in": [ "$_id", "$$subscribers" ] }}}},
      { "$count": "count" }
    ],
    "as": "lookupresult"
  }},
  { "$project": {
    "channel":  1,
    "unSubscribers": { "$arrayElemAt": [ "$lookupresult.count", 0 ] }
  }}
])
Run Code Online (Sandbox Code Playgroud)