【问题标题】:mongodb group by minMongoDB 按分钟分组
【发布时间】:2015-06-13 02:26:39
【问题描述】:

我有一张桌子:

id   value   date
1      1     2014-08-10 10:00:00
1      2     2014-08-10 10:05:00
1      1     2014-08-10 12:00:00
1      1     2014-08-11 12:05:00
1      2     2014-08-11 12:06:00
2      2     2014-08-10 10:00:00
2      2     2014-08-11 10:05:00
2      1     2014-08-11 12:00:00
2      1     2014-08-20 12:05:00
2      2     2014-08-20 12:06:00

我想获取第一天每个 id 的值的总数。我可以在 MySQL 中使用以下命令:

SELECT test.id, COUNT(CASE WHEN value=1 THEN 1 END) AS 'total_value_1',
                COUNT(CASE WHEN value=2 THEN 1 END) AS 'total_value_2'
FROM test,    
(SELECT id, date(min(date)) as firstDay
 FROM test
 GROUP BY id) AS temp
WHERE  test.id = temp.id AND date(test.date) = temp.firstDay
GROUP BY test.id;

结果是:

id total_value_1 total_value_2
1         2           1
2         0           1

我如何在 MongoDB 中做到这一点?

【问题讨论】:

  • 我决定不使用 MongoDB,但我仍然想知道答案。

标签: mongodb group-by min


【解决方案1】:

这可以通过聚合框架实现,您可以在其中使用 a collection of operators 在管道阶段定义和操作文档,从而为您提供所需的结果。您的第一个管道阶段是 $project 运算符,您可以在其中转换您的值字段,以便在以后的管道阶段进行操作。此操作的等效 SQL 为:

SELECT id, date, CASE WHEN value=1 THEN 1 END AS 'value_1',
                 CASE WHEN value=2 THEN 1 END AS 'value_2'
FROM test

接下来的管道阶段使用$group$project 运算符来计算日期字段上的最小日期以及转换后的值字段上的总和:

db.test.aggregate([
    {        
        "$project": {  
            "id": 1,            
            "date": 1,            
            "value_1": { "$cond": [{ "$eq": [ "$value", 1 ] }, 1, 0] },
            "value_2": { "$cond": [{ "$eq": [ "$value", 2 ] }, 1, 0] }
        }
    },
    {
        "$group": {
            "_id": {
                "id": "$id",
                "date": "$date"
            },
            "minimumDayofMonth": {
                "$min": { "$dayOfMonth": "$date"}
            },
            "total1" : {
                "$sum": "$value_1"
            },
            "total2" : {
                "$sum": "$value_2"
            }             
        }
    },
    {
        "$group": {
            "_id": {
                "id": "$_id.id",
                "day": "$minimumDayofMonth"
            }, 
            "firstDay": { "$min": "$minimumDayofMonth"  },            
            "total_value_1" : {
                "$sum": "$total1"
            },
            "total_value_2" : {
                "$sum": "$total2"
            }            
        }
    },
    {
        "$group": {
            "_id": "$_id.id",             
            "result": { "$first": "$$ROOT" }                
        }
    },
    {        
        "$project": {  
            "_id": 0,
            "id": "$_id",
            "total_value_1": "$result.total_value_1",
            "total_value_2": "$result.total_value_2"
        }
    }    
])

输出

/* 0 */
{
    "result" : [ 
        {
            "id" : 2,
            "total_value_1" : 0,
            "total_value_2" : 1
        }, 
        {
            "id" : 1,
            "total_value_1" : 2,
            "total_value_2" : 1
        }
    ],
    "ok" : 1
}

【讨论】:

  • 感谢您的明确答复。我通过更改日期尝试了查询。我认为 "$min": { "$dayOfMonth": "$date"} 有问题。当我更改表中的最小日期或将最小值转换为最大值时。我得到相同的结果。另外,当我写 min dayOfMonth 时,它不会返回所有月份中的最小天数吗?例如:“2014-08-10”、“2014-10-01”。
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 2019-06-06
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 2015-01-05
相关资源
最近更新 更多