MongoDB查询以获取密钥发生的次数

时间:2013-01-31 19:22:01

标签: php mongodb grouping

所以我有一个跟踪我们应用登录的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获得完整的答案。 另一个限制(即使在我超越第一组之后)是我希望按日期做一个独特的计数......这将更加艰难!

3 个答案:

答案 0 :(得分: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 ) ) )
));

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

注意:如注释中所述,聚合帮助程序是PHP驱动程序的1.3+版本。在1.3版之前,您必须直接使用command函数。

答案 1 :(得分: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甚至更多,走路和组合它们不会有问题,所以不用担心性能。

答案 2 :(得分: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个唯一条目,所以它真的不适合你。