假设我有两个MongoDb集合(带有示例字段):
People:
_id: 2
name: 'bob'
carIds: [1,2,3]
和
Cars:
_id: 82
model: 'Camry'
是否可以使用新字段People
返回Cars
列表,该字段Cars
的数组carId
的{{1}}匹配carIds
人们。
我不想永久创建字段,仅用于查询结果。我可以用某种方式用地图做这个吗?我试过了:
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,但这会强制返回项目,而不是查询它们。
答案 0 :(得分:3)
find()方法返回一个游标。您需要将其转换为数组(cursor.toArray()IIRC)。这应该可以解决你的问题。
var cars= db.find(...).toArray()
但说实话,如果你想经常使用这个查询,这不是最好的设计。你最好添加一个字段' personId'通过单一查询到汽车并查询汽车收藏。
答案 1 :(得分:0)
使用单个查询可以采用的一种方法是使用聚合框架并运行具有 $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" }
}
}
])