假设我有两个MongoDb集合(带有示例字段):
People:
_id: 2
name: 'bob'
carIds: [1,2,3]
和
Cars:
_id: 82
model: 'Camry'
有没有一种方法可以返回一个带有新字段Cars
的People
列表,该字段将具有一个Cars
数组,该数组具有与People中的carIds
匹配的carId
。
我不想永久性地创建字段,只是为了查询结果。我能用地图做这个吗?我试过了:
var peopleWithCars = db.people.find({
}).map(function(doc) {
var carIds = doc.carIds;
var cars = db.cars.find({
_id: { $in: carIds}
})
doc.cars= cars;
return doc;
});
return peopleWithCars ;
得到:
错误:第18行:非法的返回语句
编辑-这就是最终奏效的:
db.people.find({
}).map(function(doc) {
var carIds = doc.carIds;
var cars = db.cars.find({
_id: { $in: carIds}
}).toArray();
doc.cars= cars;
return doc;
});
出于某种原因,它仍然不喜欢vars,但这会强制返回项,而不是查询它们。
var cars= db.find(...).toArray()
但老实说,如果你想经常使用这个查询,那不是最好的设计。您最好在car中添加一个字段"personId",然后用一个查询来查询cars集合。
对单个查询可以采取的一种方法是使用聚合框架并运行具有$lookup
运算符的管道。这将对同一数据库中的未排序集合执行左外部联接,以筛选"联接"集合中的文档进行处理。$lookup
阶段在输入文档中的字段与"联接"集合的文档中的域之间进行相等匹配。
以下示例显示了如何将其应用于您的案例:
db.people.aggregate([
{ "$unwind": "$carIds" },
{
"$lookup": {
from: "cars",
localField: "carIds",
foreignField: "_id",
as: "cars"
}
},
{ "$unwind": "$cars" },
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"cars": { "$push": "$cars" }
}
}
])