0

所以我有一个 MongoDB 文档来跟踪登录到我们的应用程序。基本结构是这样出现的:

 [_id] => MongoId Object
        (
            [$id] => 50f6da28686ba94b49000003
        )

    [userId] => 50ef542a686ba95971000004
    [action] => login
    [time] => 1358354984

现在 - 挑战是这样的:这些条目大约有 20,000 个。我一直面临着查看每个用户登录的次数(由 userId 定义)的挑战......所以我正在寻找一种好方法来做到这一点。我见过几种可能的方法(例如,在 SQL 中,我可能会通过按 UserID 分组并对其进行计数来降低登录次数 - 例如 SELECT userID, count(*) from... .group by UserId ...然后对其进行子选择(CASE WHEN或顶部选择中的某些内容)。无论如何 - 想知道是否有人对最好的方法有任何建议。最坏的情况我可以限制结果集并在内存中进行分组 - 但理想情况下希望直接从 Mongo 获得完整答案。另一个限制(即使在我通过第一组之后)是我希望按日期进行唯一计数......

4

3 回答 3

2

现在 - 挑战是这样的:这些条目大约有 20,000 个。

在 20,000 时,使用聚合框架( http://docs.mongodb.org/manual/applications/aggregation/ )可能会更好:

$db->user->aggregate(array(
    array( '$group' => array( '_id' => '$userId', 'num_logins' => array( '$sum' => 1 ) ) )
));

这将分组(http://docs.mongodb.org/manual/reference/aggregation/#_S_groupuserId并计数(总和:http ://docs.mongodb.org/manual/reference/aggregation/sum/#_S_sum )分组登录的数量。

注意:如评论中所述,聚合帮助程序位于 PHP 驱动程序的 1.3+ 版本中。在 1.3 版本之前,您必须command直接使用该功能。

于 2013-01-31T19:29:44.950 回答
0

http://docs.mongodb.org/manual/reference/command/group/

db.user.group({key: {userId: 1}, $reduce: function ( curr, result ) { result.total++ }, initial: {total: 0}});

我只用了几秒钟就在 191000 行上运行了这个,但组被限制为 20,000 个唯一条目,所以它真的不是你的解决方案。

于 2013-01-31T19:35:00.170 回答
0

您可以使用 MapReduce 按用户 ID 对结果进行分组

http://docs.mongodb.org/manual/applications/map-reduce/#map-reduce-examples

或者您可以使用 Group 方法:

db.logins.aggregate(
    { $group : {
        _id : "$userId",
        loginsPerUser : { $sum : 1 }
    }}
);

对于 MongoDB 20K 甚至更多,走路和组合它们都不是问题,所以不用担心性能。

于 2013-01-31T19:25:23.403 回答