我有两个集合:
车辆:
[
{
"_id": "a1",
"type:": "car",
"make": "Honda",
"specifications": ["1", "2"]
},
{
"_id": "a2",
"type:": "car",
"make": "Toyota",
"specifications": ["3", "4"]
},
{
"_id": "a3",
"type:": "car",
"make": "Honda",
"specifications": []
},
{
"_id": "a4",
"type:": "car",
"make": "Toyota"
}
]
规格:
[
{
"_id": "1",
"color": "Black"
},
{
"_id": "2",
"sunroof": "yes"
},
{
"_id": "3",
"engine": "1800 CC"
},
{
"_id": "4",
"bodyType": "Sedan"
}
]
我想获取那些至少有一个规范的记录。此外,规范集合中的详细信息应显示在车辆集合中的某个位置。
预期响应:
[
{
"_id": "a1",
"make": "Honda",
"type:": "car",
"carSpecifications": [
{
"color": "Black"
},
{
"sunroof": "yes"
}
],
},
{
"_id": "a2",
"make": "Toyota",
"type:": "car",
"specifications": [
{
"engine": "1800 CC"
},
{
"bodyType": "Sedan"
}
]
}
]
到目前为止,我尝试的是:
db.vehicles.find({type: "car", "specifications": {$exists: true}}, {fields: {"specifications.$": 1}}).fetch()
此查询返回车辆中的所有记录。
在获得所有记录后,我对获得的记录进行循环,并手动检查if specifications.length > 0
,然后相应地从Specification集合中查询。
我可以通过一个查询实现所有这些吗?
您应该查找聚合查询。
-
$match
-筛选"type:" "car"
和specifications
不是空数组的文档(对于$ifNull
,当specifications
字段为null
或不存在时,默认为[]
(。 -
$lookup
-车辆集合加入规范集合(请参阅使用数组的$lookup(。使用pipeline
返回不包含_id
字段的数组(请参阅使用简明语法的相关子查询(。
MongoDB v5查询
db.vehicles.aggregate({
$match: {
$and: [
{
"type:": "car"
},
{
$expr: {
$ne: [
{
$ifNull: [
"$specifications",
[]
]
},
[]
]
}
}
]
}
},
{
$lookup: {
from: "specifications",
localField: "specifications",
foreignField: "_id",
pipeline: [
{
$project: {
_id: 0
}
}
],
as: "specifications"
}
})
Mongo Playground(v5(示例
MongoDB v4查询
db.vehicles.aggregate({
$match: {
$and: [
{
"type:": "car"
},
{
$expr: {
$ne: [
{
$ifNull: [
"$specifications",
[]
]
},
[]
]
}
}
]
}
},
{
$lookup: {
from: "specifications",
let: {
specifications: "$specifications"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$specifications"
]
}
}
},
{
$project: {
_id: 0
}
}
],
as: "specifications"
}
})
Mongo Playground(v4(示例