【问题标题】:MongoDB query to get number of times a Key occursMongoDB查询以获取键出现的次数
【发布时间】:2013-01-31 19:22:00
【问题描述】:

所以我有一个 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 获得完整的答案。 另一个限制(即使在我通过第一组之后)是我希望按日期进行唯一计数......这将更加困难!

【问题讨论】:

  • 您找到问题的解决方案了吗?

标签: php mongodb grouping


【解决方案1】:

现在,挑战是:这些条目大约有 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)分组登录的数量。

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

【讨论】:

  • 请记住,只有最新版本的 mongodb 驱动程序才支持此功能。
  • 是的-我尝试将安装驱动程序升级到 1.3-但没有 setSlaveOkay() 我正在苦苦挣扎-所以我恢复了。可能是时候弄清楚了!
  • @FernandoPombeiro Slaveokay 现在应该通过阅读偏好设置php.net/manual/en/mongo.readpreferences.php 你想使用:RP_SECONDARY
  • 是的 - RP_SECONDARY 有问题...遇到旧的“非主控”错误...需要在某个时候解决这个问题 :-)
  • @FernandoPombeiro 便便,与此同时,您始终可以通过以下命令运行它:stackoverflow.com/questions/11290809/mongodb-aggregation-php
【解决方案2】:

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

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

或者你可以使用 Group 方法:

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

对于 20K 甚至更多的 MongoDB,行走和组合它们不会有问题,所以不用担心性能。

【讨论】:

  • 是的-我想过...但是我在超时时被杀死(有超过 20,000 个键-这意味着 PHP 组功能被取消了)。
【解决方案3】:

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 个唯一条目,所以它真的不适合你。

【讨论】:

    猜你喜欢
    • 2011-08-31
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2018-09-16
    • 2018-09-20
    相关资源
    最近更新 更多