MongoDb - 在嵌套数组

时间:2015-10-29 19:15:37

标签: arrays mongodb mongoose mongodb-query

我希望有人可以对我所拥有的这个问题有所了解,这让我疯狂到过去三天我一直在学习的东西,越来越多地了解mongoDB,但仍然无法弄清楚这个简单的查询

我需要做的是获取包含“carId”=“3C”的对象。

换句话说,我希望查询返回的对象是:

            {
                "carId" : "3C", 
                "_id" : ObjectId("51273329b64f07a40ef1c15e")
            }

这是数据集(汽车):

   { 
        "_id" : ObjectId("56223329b64f07a40ef1c15c"), 
        "username" : "john", 
        "email" : "john@john.com", 
        "accounts" : [
            {
                "_id" : ObjectId("56322329b61f07a40ef1c15d"), 
                "cars" : [
                    {
                        "carId" : "6A", 
                        "_id" : ObjectId("56323329b64f07a40ef1c15e")
                    },
                    {
                        "carId" : "6B", 
                        "_id" : ObjectId("56323329b64f07a40ef1c15e")
                    }
                ]
            }
        ]
    },
    { 
        "_id" : ObjectId("56223125b64f07a40ef1c15c"), 
        "username" : "paul", 
        "email" : "paul@paul.com", 
        "accounts" : [
            {
                "_id" : ObjectId("5154729b61f07a40ef1c15d"), 
                "cars" : [
                    {
                        "carId" : "5B", 
                        "_id" : ObjectId("56323329854f07a40ef1c15e")
                    }
                ]
            },
            {
                "_id" : ObjectId("56322117b61f07a40ef1c15d"), 
                "cars" : [
                    {
                        "carId" : "6G", 
                        "_id" : ObjectId("51212929b64f07a40ef1c15e")
                    },
                    {
                        "carId" : "3C", 
                        "_id" : ObjectId("51273329b64f07a40ef1c15e")
                    },
                    {
                        "carId" : "4N", 
                        "_id" : ObjectId("51241279b64f07a40ef1c15e")
                    }
                ]
            }
        ]
    }

请注意,我有两个嵌套数组,显然MongoDb在处理深度数组的投影方面缺乏。 $运算符只能在投影中使用一次;如何完成这个简单的任务,没有任何线索。

所以我想再次找到--only--包含“carId”的文件:“3C”并且仅返回包含“carId”的直接obj:“3C”。但不是父对象。

任何帮助都会非常感激。可能使用直接MongoDb或Mongoose。猫鼬将是首选。

至于参考,我已经涵盖了这些其他相关问题无法弄明白。

Updating a deep record in MongoDb

How to Update Multiple Array Elements in mongodb

希望将来,这个问题和你的解决方案能够帮助他人。

2 个答案:

答案 0 :(得分:7)

阿米尔,

您必须使用Aggregation Framework。您可以构建一个管道,通过几个构建块处理流文档:过滤,投影,分组,排序等。

处理嵌套数组时,必须使用$unwind命令。您可以通过执行以下操作获得所需内容。

db.cars.aggregate(
    //De-normalized the nested array of accounts
    {"$unwind": "$accounts"},
    //De-normalized the nested array of cars
    {"$unwind": "$accounts.cars"},
    //match carId to 3C
    {"$match": {"accounts.cars.carId" : "3C"}},
    //Project the accoutns.cars object only
    {"$project" : {"accounts.cars" : 1}},
    //Group and return only the car object
    {"$group":{"_id":"$accounts.cars"}}
).pretty();

您可以使用$unwind

将聚合框架用于“数组过滤”

您可以在上面的代码中删除聚合管道中每个命令底部的每一行,以观察管道行为。

答案 1 :(得分:1)

这是没有聚合框架的示例。我不认为有一种方法纯粹来自查询,你将能够得到你正在寻找的单个嵌套对象,所以你必须做一些后期处理工作。像Mongoose这样的东西可能提供了一种方法来做到这一点,但我并没有真正了解Mongoose API目前的样子。

var doc = db.cars.findOne({"accounts.cars" : {$elemMatch: {"carId" : "3C"}}}, {"accounts.cars.$": 1, _id: 0})
var car = doc.accounts[0].cars[0]