MongoDB多列分组统计不同值的数量和总和函数

3
我有一个交易表,记录员工休假情况。我需要在mongodb中实现以下SQL场景:

选择employee、month、year、count(distinct(holiday_type))和sum(hours),从transactions按employee、month、year分组。

我几周前开始使用mongodb。我通过stackoverflow发帖Mongodb count distinct with multiple group fields获得了部分答案,现在我想要添加sum函数。

任何指导都将非常有帮助,这里是表格形式的数据示例:

Employee    date      holiday_type  hours
1           1/1/2014  1             8 
1           1/5/2014  2             7 
1           2/15/2014 1             8 
1           3/15/2014 3             16 
11          1/1/2014  1             8 
11          1/5/2014  1             6 
11          2/15/2014 3             8 
11          3/15/2014 3             8

什么是“hours”?它来自哪里?您可以展示一些样本数据,以便我们有一个概念吗? - Neil Lunn
1个回答

4
所以,实际上,“hours”是您的文档中的一个字段(属性)。因此,从先前的答案中,您只需按如下方式抽象出双重分组:
db.transactions.aggregate([
    { "$group": { 
        "_id": { 
            "employee" : "$employee",
            "Month": { "$month" : "$date" }, 
            "Year": { "$year" : "$date" },
            "holiday_type" : "$holiday_type"
        },
        "hours": { "$sum": "$hours" }
     }},
     { "$group": {
         "_id": {
            "employee" : "$_id.employee",
            "Month": "$_id.Month",
            "Year": "$_id.Year"
         },
         "count": { "$sum": 1 },
         "hours": { "$sum": "$hours" }
     }}
 ], { "allowDiskUse": true }
 );

所以你只是在两个阶段中都使用$sum

此外,你应该看一下官方文档中提供的SQL到聚合映射表。它有许多常见SQL操作的示例,以及如何在MongoDB中实现它们。


从您自己的数据开始,但是我以这种方式插入:

db.transactions.insert([
    { "employee": 1,  "date": new Date("2014-01-01"), "holiday_type":  1, "hours": 8   },
    { "employee": 1,  "date": new Date("2014-01-05"), "holiday_type":  2, "hours": 7   },
    { "employee": 1,  "date": new Date("2014-02-15"), "holiday_type":  1, "hours": 8   },
    { "employee": 1,  "date": new Date("2014-03-15"), "holiday_type":  3, "hours": 16  },
    { "employee": 11, "date": new Date("2014-01-01"), "holiday_type":  1, "hours": 8   },
    { "employee": 11, "date": new Date("2014-01-05"), "holiday_type":  1, "hours": 6   },
    { "employee": 11, "date": new Date("2014-02-15"), "holiday_type":  1, "hours": 8   },
    { "employee": 11, "date": new Date("2014-03-15"), "holiday_type":  3, "hours": 8   }
])

虽然所有月份实际上都不同,但这并不是最好的例子。如果需要按“holiday_type”进行分组,则此方法可以获得“distinct”值。结果如下:

{
    "_id" : {
            "employee" : 1,
            "Month" : 2,
            "Year" : 2014
    },
    "count" : 1,
    "hours" : 8
}
{
    "_id" : {
            "employee" : 11,
            "Month" : 2,
            "Year" : 2014
    },
    "count" : 1,
    "hours" : 8
}
{
    "_id" : {
            "employee" : 1,
            "Month" : 1,
            "Year" : 2014
    },
    "count" : 2,
    "hours" : 15
}
{
    "_id" : {
            "employee" : 11,
            "Month" : 1,
            "Year" : 2014
    },
    "count" : 1,
    "hours" : 14
}
{
    "_id" : {
            "employee" : 1,
            "Month" : 3,
            "Year" : 2014
    },
    "count" : 1,
    "hours" : 16
}
{
    "_id" : {
            "employee" : 11,
            "Month" : 3,
            "Year" : 2014
    },
    "count" : 1,
    "hours" : 8
}

谢谢@Neil。我尝试了这个,但小时列上得到的是零。样本数据集如下: "employee" : "Karthick" <br /> "holiday_type" : 1 <br /> "hourrs" : 8, <br /> "date" : 2009-01-01" <br /> <br /> "employee" : "Karthick11" <br /> "holiday_type" : 1 <br /> "hourrs" : 8, <br /> "date" : 2009-01-01" <br /> <br /> "employee" : "Karthick12" <br /> "holiday_type" : 1 <br /> "hourrs" : 8, <br /> "date" : 2009-01-01" <br /> <br /> - Karthi
@Karthi,你的hourrs字段拼写不同(而且不正确),所以你不能只是“剪切和粘贴”,而是需要查看差异。此外,这真的应该是对你的问题进行编辑,因为我已经从你之前的评论中尝试过了。所以请在将来编辑你的问题,而不是尝试在评论中发布其他细节(特别是数据)。但我认为一般的问题值得展示概念,所以你得到了一个赞成票。 - Neil Lunn
谢谢您的建议。在我的实时数据中,只提到了“小时”。我只是用样本数据填充并拼错了。还可能出了什么问题? - Karthi
@Karthi,你的设置明显有问题。请查看我在答案中提供的附加信息。如所示的查询按预期工作。 - Neil Lunn
这个程序正在运行。我的查询中有错误。非常感谢你,尼尔。我现在清楚地理解了这个逻辑。 - Karthi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接