MongoDB按小时汇总并总结错误结果

时间:2018-06-20 15:00:24

标签: mongodb

所以我有一份与此文件有关的收藏

 { 
    "_id" : {
        "ad_id" : NumberInt(1915577), 
        "createdAt" : ISODate("2018-06-12T22:00:00.000+0000")
    }, 
    "history" : [
        {
            "createdAt" : ISODate("2018-06-13T13:31:23.536+0000"), 
            "mobile" : true, 
            "app" : false, 
            "origin" : NumberInt(2)
        },
        {
            "createdAt" : ISODate("2018-06-13T13:43:11.512+0000"), 
            "mobile" : true, 
            "app" : false, 
            "origin" : NumberInt(2)
        },
        {
            "createdAt" : ISODate("2018-06-13T20:31:05.156+0000"), 
            "mobile" : true, 
            "app" : false, 
            "origin" : NumberInt(6)
        },
        {
            "createdAt" : ISODate("2018-06-13T21:14:09.236+0000"), 
            "mobile" : false, 
            "app" : false, 
            "origin" : NumberInt(3)
        }
    ], 
    "impressions_mobile" : NumberInt(10),
    "impressions_desktop" : NumberInt(3),
}

我想获取我的历史记录数组中有多少“移动”和“非移动”项目,并按一天中的每个小时(从00到23小时)进行分组

[
    {
        "_id": {
            "y": 2018,
            "m": 6,
            "d": 13,
            "h": 13
        },
        "mobile": 4,
        "desktop": 3
    },
    {
        "_id": {
            "y": 2018,
            "m": 6,
            "d": 13,
            "h": 20
        },
        "mobile": 6,
        "desktop": 3
    }
]

我已经尝试过像这样的查询,但没有结果...如果删除$unwind和组_id对象(将其设置为null),则会得到数字。我尝试了许多其他查询,但无法正常工作。

基本上,我想按天和小时对结果进行分组,并获得多少结果...

db.mycol.aggregate([
    {
        $match: {
             "ad.advertiser": 1399619,
            "_id.createdAt": {
                $gte: ISODate("2018-06-12T22:00:00.000+0000"),
                $lte: ISODate("2018-06-14T22:00:00.000+0000")
            }
        }
    },
    {
      $project: {
        _id: "$history",
        mobile: {
            $filter: {
                input: "$history",
                as: "h",
                cond: { $eq: [ "$$h.mobile", true ] }
            }
        },
        desktop: {
            $filter: {
                input: "$history",
                as: "h",
                cond: { $eq: [ "$$h.mobile", false ] }
            }
        }
      }
    },
    {
      $project: {
        _id: "$history",
        mobile: { $size: "$mobile" },
        desktop: { $size: "$desktop" },
      }
    },
    { $unwind: "$_id" },
    {
        $group: {
            _id: {
                "y": {
                    "$year": "$_id.createdAt"
                },
                "m": {
                    "$month": "$_id.createdAt"
                },
                "d": {
                    "$dayOfMonth": "$_id.createdAt"
                },
                "h": {
                    "$hour": "$_id.createdAt"
                }
            },
            mobile: { $sum: "$mobile" },
            desktop: { $sum: "$desktop" }
        }
    }
])

此其他查询有效,但给我错误的结果

db.mycol.aggregate([
    {
        $match: {
             "ad.advertiser": 1399619,
            "_id.createdAt": {
                $gte: ISODate("2018-06-12T22:00:00.000+0000"),
                $lte: ISODate("2018-06-14T22:00:00.000+0000")
            }
        }
    },
    {
      $project: {
        _id: {
            $filter: {
                input: "$history",
                as: "h",
                cond: { $eq: [ "$$h.mobile", true ] }
            }
        }
      }
    },
    { $project: { _id: "$_id",  mobile: { $size: "$_id" } } },
    { $unwind: "$_id" },
    {
        $group: {
            _id: {
                "y": {
                    "$year": "$_id.createdAt"
                },
                "m": {
                    "$month": "$_id.createdAt"
                },
                "d": {
                    "$dayOfMonth": "$_id.createdAt"
                },
                "h": {
                    "$hour": "$_id.createdAt"
                }
            },
            mobile: { $sum: "$mobile" }
        }
    }
])

字段mobile输出一个巨大的数字,例如,它代替了〜200(这是真实的结果),它给出了〜8000,但我不知道它在做什么...

我很想同时获得台式机和移动设备的结果,但我不介意在两个查询中得到它

更新:我粘贴了错误的查询,对不起^^'

UPDATE2: $_id.createdAt始终是午夜日期(以UTC表示,因此是22h),集合中的每个文档都被视为“在这一天,我们有这个”,然后在history字段中有事情发生的时间。

如果我在_id.createdAt字段中按小时分组,则所有内容将在同一小时内,而不是一天24小时。

例如,按_id.createdAt分组的结果将始终为 { "y": 2018, "m": 6, "d": 13, "h": 00, "mobile": 100, "desktop": 35 } 因此,_id.createdAt仅用于匹配该特定日期,并且仅用于该日期。

1 个答案:

答案 0 :(得分:0)

使用&操作求和:

$cond