减少mongoDB查询的响应

时间:2014-03-27 13:58:23

标签: mongodb mongodb-query aggregation-framework

我有这样的文件:

{
    "_id" : ObjectId("53340d07d6429d27e1284c77"),
    "worktypes" : [ 
        {
            "name" : "Pompas",
            "works" : [ 
                {
                    "name" : "work 1",
                    "code" : "0001"
                }
            ]
        },
        {
            "name" : "Pompas "",
            "works" : [ 
                {
                    "name" : "work 2",
                    "code" : "0002"
                }
            ]
        }
    ]
}

我只查询了本文档的工作类型之一的作品,这是查询:

db.categories.find({$and: [
        { "_id": ObjectId('53340d07d6429d27e1284c77')},
        {"worktypes.name": "Pompas"}
    ]},{"worktypes.works.$":1})

但我得到了

    {
    "_id" : ObjectId("53340d07d6429d27e1284c77"),
    "worktypes" : [ 
        {
            "name" : "Pompas",
            "works" : [ 
                {
                    "name" : "work 1",
                    "code" : "0001"
                }
            ]
        }
    ]
}

但我只需要:

"works" : [ 
                    {
                        "name" : "work 1",
                        "code" : "0001"
                    }
                ]

我该如何减少这个?

3 个答案:

答案 0 :(得分:12)

我认为Neil Lunn's answer大部分是正确的,但在我看来,需要进行一些调整才能获得预期效果:

  1. "worktypes.name"而不是"worktypes.works.name"
  2. 匹配
  3. $group阶段,使用$first代替$push来获取第一个元素
  4. 添加$project阶段以获取"works"
  5. db.categories.aggregate([
        { "$unwind": "$worktypes" },
        { "$unwind": "$worktypes.works" },
        { "$match": {
            "worktypes.name": "Pompas"
        }},
        { "$group": {
            "_id": "$_id",
            "works": { "$first": "$worktypes.works" }
        }},
        { "$project": {"_id":0, "works":1} }
    ])
    

    <强>输出:

    {
            "result" : [
                    {
                            "works" : {
                                    "name" : "work 1",
                                    "code" : "0001"
                            }
                    }
            ],
            "ok" : 1
    }
    

答案 1 :(得分:2)

使用数组时需要使用$unwind运算符:

db.catefories.aggregate([

    // Unwind the first array
    { "$unwind": "$worktypes" },

    // Then unwind the embedded array
    { "$unwind": "$worktypes.works" },

    // Match the item you want
    { "$match": {
        "worktypes.works.name": "work 1"
    }},

    // Group to reform the array structure
    { "$group": {
        "_id": "$_id",
        "worktypes": { "$push": "$worktypes" }
    }}
])

要以$group之后使用$unwind作为数组返回。

答案 2 :(得分:0)

您可以选择性地从投影中删除字段,如下所示:

db.categories.find({$and: [
    { "_id": ObjectId('53340d07d6429d27e1284c77')},
    {"worktypes.name": "Pompas"}
]},{"worktypes.works.$":1, _id:0 })

这将阻止投影_id字段。