$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"
}
]
我在 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"
}
]