Mongodb Aggregation和Group By查询

时间:2014-09-12 11:24:59

标签: node.js mongodb mongoose

我有一组存储在mongodb中的篮子,如:

/* 47 */
{
    "_id" : ObjectId("535ff14c2e441acf44708ec7"),
    "tip" : "0",
    "basketTransactionCash" : "2204",
    "basketTransactionCard" : "0",
    "completed" : ISODate("2014-04-07T14:35:17.000Z"),
    "consumerId" : null,
    "storeId" : 1,
    "basketId" : 210048,
    "basketProduct" : [ 
        {
            "_id" : ObjectId("535feffa2e441acf446facb7"),
            "name" : "Vanilla Spice Hot Chocolate",
            "productId" : 23,
            "basketProductInstanceId" : 838392,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "633",
            "vatPercentage" : "0.2"
        }
    ],
    "created" : ISODate("2014-04-07T14:35:42.000Z"),
    "__v" : 0
}

/* 48 */
{
    "_id" : ObjectId("535ff14c2e441acf44708ede"),
    "tip" : "0",
    "basketTransactionCash" : "230",
    "basketTransactionCard" : "0",
    "completed" : ISODate("2014-04-07T14:41:51.000Z"),
    "consumerId" : 1,
    "storeId" : 1,
    "basketId" : 210072,
    "basketProduct" : [ 
        {
            "_id" : ObjectId("535feffa2e441acf446facf3"),
            "name" : "Melon",
            "productId" : 4544,
            "basketProductInstanceId" : 838430,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "200",
            "vatPercentage" : "0"
        }, 
        {
            "_id" : ObjectId("535feffa2e441acf446facf4"),
            "name" : "30p",
            "productId" : 8496,
            "basketProductInstanceId" : 838431,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "30",
            "vatPercentage" : "0"
        }
    ],
    "created" : ISODate("2014-04-07T14:42:16.000Z"),
    "__v" : 0
}

/* 49 */
{
    "_id" : ObjectId("535ff14c2e441acf44708ee2"),
    "tip" : "0",
    "basketTransactionCash" : "2204",
    "basketTransactionCard" : "0",
    "completed" : ISODate("2014-04-07T14:41:54.000Z"),
    "consumerId" : 2,
    "storeId" : 1,
    "basketId" : 210076,
    "basketProduct" : [ 

        {
            "_id" : ObjectId("535feffb2e441acf446fad02"),
            "name" : "Creamy Natural Yoghurt",
            "productId" : 69,
            "basketProductInstanceId" : 839800,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "911.7",
            "vatPercentage" : "0.2"
        }, 
        {
            "_id" : ObjectId("535feffb2e441acf446fad03"),
            "name" : "Melon",
            "productId" : 4544,
            "basketProductInstanceId" : 839801,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "200",
            "vatPercentage" : "0"
        }, 
        {
            "_id" : ObjectId("535feffb2e441acf446fad04"),
            "name" : "30p",
            "productId" : 8496,
            "basketProductInstanceId" : 839802,
            "quantity" : 1,
            "productModifiedPrice" : null,
            "productInstancePrice" : "30",
            "vatPercentage" : "0"
        }
    ],
    "created" : ISODate("2014-04-07T14:43:00.000Z"),
    "__v" : 0
}  

我可以按小时完成分组吗?所以最终结果应该类似于下面的

{
        "totalTip" : "0",
        "basketTransactionCashTotal" : "4638",
        "basketTransactionCardTotal" : "0",
        "completed" : "2014-04-07 14",
        "consumerIds" : [null, 1, 2],
        "storeId" : 1,
        "basketIds" : [210048, 210072, 210076]
        "basketProduct" : [ 
            {
                "_id" : ObjectId("535feffa2e441acf446facf3"),
                "name" : "Melon",
                "productId" : 4544,
                "basketProductInstanceId" : 838430,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "200",
                "vatPercentage" : "0"
            }, 
            {
                "_id" : ObjectId("535feffa2e441acf446facf4"),
                "name" : "30p",
                "productId" : 8496,
                "basketProductInstanceId" : 838431,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "30",
                "vatPercentage" : "0"
            },
            {
                "_id" : ObjectId("535feffb2e441acf446fad02"),
                "name" : "Creamy Natural Yoghurt",
                "productId" : 69,
                "basketProductInstanceId" : 839800,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "911.7",
                "vatPercentage" : "0.2"
            }, 
            {
                "_id" : ObjectId("535feffb2e441acf446fad03"),
                "name" : "Melon",
                "productId" : 4544,
                "basketProductInstanceId" : 839801,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "200",
                "vatPercentage" : "0"
            }, 
            {
                "_id" : ObjectId("535feffb2e441acf446fad04"),
                "name" : "30p",
                "productId" : 8496,
                "basketProductInstanceId" : 839802,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "30",
                "vatPercentage" : "0"
            },
            {
                "_id" : ObjectId("535feffa2e441acf446facb7"),
                "name" : "Vanilla Spice Hot Chocolate",
                "productId" : 23,
                "basketProductInstanceId" : 838392,
                "quantity" : 1,
                "productModifiedPrice" : null,
                "productInstancePrice" : "633",
                "vatPercentage" : "0.2"
            }
        ]
    }

有人可以帮我理解这个节点中的mongoose吗?

1 个答案:

答案 0 :(得分:3)

首先,字段tipbasketTransactionCashbasketTransactionCard 需要转换为数字类型才能执行任何算术运算。您可以查看this question以获取使用正确数据类型更新所有文档的方法。

完成数据类型后,您可以使用aggregation framework来接近您想要的内容。 date aggregation operators提供了按小时分组的方法。示例查询如下:

db.collection.aggregate([
{
    "$group": {
        "_id": {
            "year": {"$year": "$completed"},
            "month": {"$month": "$completed"},
            "day": {"$dayOfMonth": "$completed"},
            "hour": {"$hour": "$completed"}
        },
        "totalTip": {
            "$sum": "$tip"
        },
        "basketTransactionCashTotal": {
            "$sum": "$basketTransactionCash"
        },
        "basketTransactionCardTotal": {
            "$sum": "$basketTransactionCard"
        },
        "consumerIds": {
            "$push": "$consumerId"
        },
        "storeId": {
            "$addToSet": "$storeId"
        },
        "basketIds": {
            "$push": "$basketId"
        },
        "basketProducts": {
            "$push": "$basketProduct"
        }
    }
}
])

我建议你阅读一下聚合内容并稍微介绍它,因为它是一个非常强大的工具。

注意:除非数据类型已更新,否则totalTipbasketTransactionCashTotal和{{1}的 0 0 }