$lookup 当 localfield 可能不存在时 MongoDb

$lookup when localfield may not exist MongoDb

我在 MongoDB 4.0 (pymongo)

中有三个集合
users: [
{name: "John", house_id: 1, car_id: 1},
{name: "Charles", house_id: 1},
{name: "Jessy", house_id: 2, car_id: 2},
{name: "Tim", house_id: 3}
]

houses: [
{_id: 1, name: "house1"},
{_id: 1, name: "house2"},
{_id: 1, name: "house3"}
]

cars: [
{_id: 1, name: "car1"},
{_id: 2, name: "car2"}
]

在用户 table 中,house_id 是必需的,但 car_id 不需要。 我需要在用户、房屋和汽车之间进行连接,以获得包含房屋信息和汽车信息的用户列表,如果他们有 car_id.

这是我的脚本

db.users.aggregate([{                                   
  "$lookup": {
    "from": "houses",
    "localField": "house_id",
    "foreignField": "_id",
    "as": "house"
  }
},
{"$unwind": "$house"},
{                                   
  "$lookup": {
    "from": "cars",
    "localField": "car_id",
    "foreignField": "_id",
    "as": "car"
  }
},
{"$unwind": "$car"}]);

但此脚本 return 仅限 car_id 的用户。如果我添加一个 $match 和 un user._id 而没有 car_id,我没有结果。

我知道 car_id 需要在这里才能得到结果,但就我而言,我需要得到所有结果。

没有 car_id 的用户的预期输出:

[
  {
    "_id": ObjectId("xxxxxxxxxx"),
    "name": "Charles"
    "house_id": 1,
    "houses": {
      "_id": 1,
      "name": "house1"
    },
  }
]

我不确定您希望输出是什么样子,但您可以通过在 $lookups 之前添加匹配项来实现。

你可以看看live demo of this query here

数据库

考虑以下数据库。

db={
  users: [
    {
      name: "John",
      house_id: 1,
      car_id: 1
    },
    {
      name: "Charles",
      house_id: 1
    },
    {
      name: "Jessy",
      house_id: 2,
      car_id: 2
    },
    {
      name: "Tim",
      house_id: 3
    }
  ],
  houses: [
    {
      _id: 1,
      name: "house1"
    },
    {
      _id: 2,
      name: "house2"
    },
    {
      _id: 3,
      name: "house3"
    }
  ],
  cars: [
    {
      _id: 1,
      name: "car1"
    },
    {
      _id: 2,
      name: "car2"
    }
  ]
}

查询

我们可以使用此查询进行嵌套查找:

db.users.aggregate([
  {
    $match: {
      name: "Charles"
    }
  },
  {
    "$lookup": {
      "from": "houses",
      "as": "houses",
      "localField": "house_id",
      "foreignField": "_id"
    }
  },
  {
    "$lookup": {
      "from": "cars",
      "as": "cars",
      "localField": "car_id",
      "foreignField": "_id"
    }
  },
  {
    $unwind: {
      path: "$cars",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$houses",
      preserveNullAndEmptyArrays: true
    }
  }
])

结果

这给了我们:

[
  {
    "_id": ObjectId("5a934e000102030405000006"),
    "house_id": 1,
    "houses": {
      "_id": 1,
      "name": "house1"
    },
    "name": "Charles"
  }
]