【问题标题】:MongoDB Aggregation PHP, Group by DaysMongoDB 聚合 PHP,按天分组
【发布时间】:2014-08-20 15:55:11
【问题描述】:

我有以下格式的数据库

Array
(
[_id] => MongoId Object
    (
        [$id] => 53f4bf0e8db0d31b0ba802df
    )

[userSession] => 580929792589634763f964479eee8721
[pageEnteredDate] => 1408548587
[pageLeftDate] => 1408548622
[userName] => User 1
[userId] => 33657
[pageView] => monitoring patients
[pageActions] => []
[pageTag] => 1-3-16-131-315
[timeSpent] => 35
)
Array
(
[_id] => MongoId Object
    (
        [$id] => 53f3d7008db0d33e61cae841
    )

[userSession] => e04e5081c9482654030bacf3c8c90b21
[pageEnteredDate] => 1408488536
[pageLeftDate] => 1408489216
[userName] => user 2
[userId] => 4278
[pageView] => Surgery Staff
[pageActions] => [["BUTTON","Comment",1408488701],["A","Discussion",1408488712]]
[pageTag] => 1-3-5-148
[timeSpent] => 680
)
Array
(
[_id] => MongoId Object
    (
        [$id] => 53f3d7008db0d33gj1cae841
    )

[userSession] => e04e5081c9482654030bahjhc8c90b21
[pageEnteredDate] => 1408488536
[pageLeftDate] => 1408489216
[userName] => user 3
[userId] => 428
[pageView] => Surgery Staff
[pageActions] => [["BUTTON","Comment",1408488701],["A","Discussion",1408488712]]
[pageTag] => 1-3-5-148
[timeSpent] => 680
)

pageEnteredDate 是我要使用的日期

我想按页面标签和日期对数据进行分组。我的意思是有一天我应该只获得一次相同的 pageTag。

因此,从这 3 个数组中它应该只显示 2 个,因为 2 个具有相同的 pageTag 并且在同一天。

谢谢

***使用的代码

$result = $this->collection->aggregate(
array(
    array(
        '$group' => array( 
            '_id'=> array( 'pageTag' => '$pageTag','day' => array('$subtract' => array('$pageEnteredDate', 86400))),
            'timeSpent' => array( '$sum' => '$timeSpent' ),
            'lastView' => array( '$max' => '$pageEnteredDate' )
        )
    ),
    array('$skip' => 0),
    array('$limit' => 20)
)

);

【问题讨论】:

    标签: php mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您的“日期”值似乎只是从纪元时间戳派生的数字(不包括毫秒)。但你真正想做的只是通过aggregation framework 申请$group,并按“天”分组:

    $result = $collection->aggregate(array(
        array(
            '$group' => array( 
                '_id' => array(
                    'pageTag' => 'pageTag',
                    'day' => array(
                        '$subtract' => array(
                            '$pageEnteredDate',
                            array('$mod' => array(
                                '$pageEnteredDate',
                                60 * 60 * 24
                            ))
                        )
                    )
                ),
                'timeSpent' => array( '$sum' => '$timeSpent' ),
                'lastView' => array( '$max' => '$pageEnteredDate' )
            )
        )
    ));
    

    这基本上是说要对“pageTag”值进行分组,并使用“pageEnteredDate”来应用基本上将时间戳四舍五入到当天的数学运算,因此同一天的所有值都是相同的。

    您还没有确切地说出您想要在这里“分组”的是什么,因此给出了将$sum 应用于“timeSpent”值并使用$max 来识别记录的最后一个时间戳值的示例那天。

    您可以通过这种方式使用任何"grouping operators" 来满足您的需求

    【讨论】:

    • 感谢您的帮助。我收到此错误:异常:$subtract 运算符需要一个包含 2 个操作数的数组。如果我用一个值替换 mod 函数是有效的。
    • @Teodor Arggh!我不喜欢 PHP 数组表示法。一般来说,如果我必须这样做,我更喜欢像 JSON 这样理智的东西,然后对其进行解码并可能进行操作。提交前我没有检查的罕见情况。缺少围绕 $mod 的包装 array() 方法
    • 还有一个问题,如果我想显示更多字段?我正在尝试使用 $project 但无法使用数组('$project' => array('pageEnteredDate' => 1, )),