Mongodb尝试从聚合中返回选定的字段

时间:2014-07-04 10:14:24

标签: node.js mongodb mongoose aggregation-framework

我的聚合功能有问题。我正在尝试从数据库中获取用户最常见的订单,但我只返回名称和计数。我已尝试使用$project运算符,但除了$group语句中的内容之外,我似乎无法返回任何内容。

这是我当前的聚合函数:

OrderModel.aggregate(
        {$unwind: "$products"},
        {$match: { customerID: customerID }},
        {$group: { _id: "$products.name", count: {$sum:1}}},
        {$project: {name: "$_id", _id:0, count:1, active:1}},
        {$sort: {"count" : -1}},
        {$limit: 25 })

这只产生如下{"count":10, "name": foo"}的输出,而我想返回整个对象;嵌入式文档和所有。我出错的任何想法?

编辑 - 添加了示例文档和预期输出

文件:

{
    "charge": {},
        "captured": true,
        "refunds": [
        ],
        "balance_transaction": "txn_104Ics4QFdqlbCVHAdV1G2Hb",
        "failure_message": null,
        "failure_code": null,
        "amount_refunded": 0,
        "customer": "cus_4IZMPAIkEdiiW0",
        "invoice": null,
        "dispute": null,
        "statement_description": null,
        "receipt_email": null
    },
    "total": 13.2,
    "userToken": "cus_4IZMPAIkEdiiW0",
    "customerID": "10152430176375255",
    "_id": "53ad927ff0cb43215821c649",
    "__v": 0,
    "updated": 20140701082928810,
    "created": 20140627154919216,
    "messageReceived": false,
    "ready": true,
    "active": false,
    "currency": "GBP",
    "products": [
        {
            "name": "Foo",
            "active": true,
            "types": [
                {
                    "variants": [
                        {
                            "name": "Bar",
                            "isDefault": false,
                            "price": 13.2
                        }
                    ]
                }
            ]
        }
    ]
}

预期结果:

[
    {
        "name": "Foo",
        "active": true,
        "types": [
            {
                "variants": [
                    {
                        "name": "Bar",
                        "isDefault": false
                    }
                ]
            },
            {
                "variants": [
                    {
                        "name": "Something else",
                        "isDefault": false
                    }
                ]
            }
        ],
        "quantity": 10
   },
   {
       "name": "Another product",
       "active": true,
       "types": [
           {
               "variants": [
                   {
                       "name": "Bar",
                       "isDefault": false
                   }
               ]
           }
       ],
       "quantity": 7
   }

谢谢!

1 个答案:

答案 0 :(得分:10)

在这里,$project主要依赖于“右手”一侧文档中字段属性的“绝对路径”。诸如1之类的快捷方式仅适用于该元素实际上是文档顶层的位置。

此外,您需要能够在$group时保留字段,因此您可以使用各种分组操作符,例如$first$addToSet$push来保留字段你从内部阵列发出的信息。此外,您必须$unwind两次,因为您要跨文档组合“类型”,并且在这种情况下您不需要$first

OrderModel.aggregate([
    { "$unwind": "$products" },
    { "$unwind": "$products.types" },
    { "$group": {
        "_id": "$products.name",
        "active": { "$first": "$products.active" },
        "types": { "$addToSet": "$products.types" },
        "quantity": { "$sum": 1 }
    }},
    { "$project": {
        "_id": 0,
        "name": "$_id",
        "active": 1,
        "types": 1,
        "quantity": 1
    }}
],function(err,results) {

});