MongoDb:将一个Collection的文档嵌入另一个Collection for Query for Results

时间:2016-07-22 14:55:06

标签: mongodb

假设我有两个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,但这会强制返回项目,而不是查询它们。

2 个答案:

答案 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" }
        }
    }
])