我有这样的文件:

{
    "_id" : "someuniqueeventid",
    "event" : "event_type_1",
    "date" : ISODate("2014-01-14T00:00:00Z"),
}

我想按"event"分组,计算一周中每天发生的每种事件类型的数量.基本上,我想得到这样的东西:

{
    "_id": "event_type_1",
    "1": "number of event_type_1 for Monday",
    "2": "number of event_type_1 for Tuesday",
    ...
},
{
    "_id": "event_type_2",
    ...
}

不幸的是,我被困在:

db.data.aggregate([ {$project: {date_of_week: {$dayOfWeek: "$date"}, event: "$event"}}, 
                    {$group: {_id: "$event", .... } ])

有什么 idea 吗?

推荐答案

聚合框架不会基于数据创建密钥,甚至你也不会这样做,因为"数据"不是密钥,而是实际数据,所以你应该坚持这种模式.

这意味着你基本上可以这么做:

db.data.aggregate([
    { "$group": {
        "_id": {
            "event_type": "$event",
            "day": { "$dayOfWeek": "$date" }
        },
        "count": { "$sum": 1 } 
    }}
])

这将统计每个事件每周每天的发生次数,尽管输出中有多个文档,但这很容易更改 for each 事件一个文档:

db.data.aggregate([
    { "$group": {
        "_id": {
            "event_type": "$event",
            "day": { "$dayOfWeek": "$date" }
        },
        "count": { "$sum": 1 } 
    }},
    { "$group": {
        "_id": "$_id.event_type",
        "days": { "$push": { "day": "$_id.day", "count": "$count" } }
    }}
])

这是一个数组形式,但它仍然保存着你想要的结果.

如果你真的一心想按自己的方式做,那么你想做这样的事情:

db.data.aggregate([
    { "$group": {
        "_id": "$event",
        "1": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 1 ] },
                    1,
                    0
                ]
            }
        },
        "2": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 2 ] },
                    1,
                    0
                ]
            }
        },
        "3": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 3 ] },
                    1,
                    0
                ]
            }
        },
        "4": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 4 ] },
                    1,
                    0
                ]
            }
        },
        "5": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 5 ] },
                    1,
                    0
                ]
            }
        },
        "6": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 6 ] },
                    1,
                    0
                ]
            }
        },
        "7": {
            "$sum": {
                "$cond": [
                    { "$eq": [{ "$dayOfWeek": "$date" }, 7 ] },
                    1,
                    0
                ]
            }
        }
    }}
)

但这真的很冗长,所以我会坚持第一个或第二个解决方案,因为它们更短,更容易阅读.

Mongodb相关问答推荐

在MongoDB查询中添加来自另一个集合的匹配文档的计数

从MongoDB中的嵌套数组中提取找到的值及其索引

获取响应周期中的特定键和值

将子元素的数组值提取到 mongodb 中的单个数组中?

如何在查找 foreignField 中使用通配符?

@DynamicPropertySource 未被调用(Kotlin、Spring Boot 和 TestContainers)

MongoDB 将 JSON 字符串转换为数组[{obj1},{obj2}]的实际对象

MongoDB 到 Snowflake 连续加载

MongoDB中的readPreference和readConcern有什么区别?

在 MongoDB 中按条件分组

如何使用 c# 2.0 驱动程序将数据插入到 mongodb 集合中?

Mongoose 是否真的验证了对象 ID 的存在?

Mongoose 不创建新集合

在 mongoDB 中展平嵌套的 JSON struct

使用 Spring Security + Spring 数据 + MongoDB 进行身份验证

mongodb:upserting:仅在插入文档时设置值

MongoDB MapReduce - 发出一个键/一个值不调用reduce

如何将转储文件夹导入 mongodb 数据库?

我需要手动关闭mongoose连接吗?

将 FilterDefinition 转换为可以在 mongo shell 中运行的常规 json mongo 查询