2016-07-22 53 views
1

比方说,我有两个MongoDB的集合(以实例字段):的MongoDB:鸟巢一个集合在另一个查询的文档的结果

People: 
_id: 2 
name: 'bob' 
carIds: [1,2,3] 

Cars: 
_id: 82 
model: 'Camry' 

有没有办法返回一个列表People与一个新字段Cars,其中将有一个Cars数组carId匹配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 ; 

,并得到:

Error: Line 18: Illegal return statement

编辑 - 这是最后的工作:

db.people.find({ 
     }).map(function(doc) { 

     var carIds = doc.carIds; 

     var cars = db.cars.find({ 
      _id: { $in: carIds} 
     }).toArray(); 

     doc.cars= cars; 

     return doc; 
    }); 

出于某种原因,它仍然不喜欢瓦尔,但是这迫使项目返回,而不是查询它们。

回答

3

find()方法返回一个游标。您需要将其转换为数组(cursor.toArray()IIRC)。这应该可以解决你的问题。

var cars= db.find(...).toArray() 

但说实话,如果你想经常使用这个查询,那不是最好的设计。您最好在汽车中添加一个字段'personId',并使用单个查询查询汽车集合。

+0

更新 - 我试过了。它仍然返回与第一个版本相同的错误。使用第二个版本(没有'var cars'),它返回'查询成功执行,但是没有结果显示' – VSO

+1

也为汽车领域做一个.toArray()。 – greyfairer

+0

toArray是什么解决它,但由于某种原因,它不起作用,如果我们运行它的人发现。但它确实迫使汽车查询执行。 Ty再次寻求帮助。 – VSO

0

您可以使用单个查询采取的一种方法是使用聚合框架并运行具有运算符的管道。这会对同一个数据库中的未加注集合执行左外部联接,以过滤“已加入”集合中的文档进行处理。 $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" } 
     } 
    } 
]) 
相关问题