在mongo中聚合集合以确定计数

时间:2015-04-23 20:56:48

标签: mongodb mongodb-query

我在MongoDB中有一个包含多个字段的集合,每次用户执行操作时都由我的应用服务器写入。一种日志集合。每个文档类似于以下模式,为简洁起见省略了一些不相关的字段:

{
        "_id" : ObjectId("5536727686e09bab576f1c94"),
        "_user" : ObjectId("5536597b60b2321aadeb8a7c"),
        "_userAgent" : "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0",
        "_systemTime" : ISODate("2015-04-21T15:53:26.272Z")
        ...
}

我本周在3月21日星期二和3月22日星期三进行了一些压力测试。我想形成一个查询,可以确定有多少不同的用户在这一天中有多少条目。 3月21日星期二有多少不同的用户至少有一个条目,以及有多少不同的用户在3月22日星期三至少有一个条目,这将是一个好方法?在祖鲁岛保留日期就足够了。

3 个答案:

答案 0 :(得分:2)

我认为你这里不需要聚合。您可以使用distinct查询以及长度来实现您想要的效果。

db.coll.distinct('_user', {
    _systemTime: {
        $gte: ISODate(some time),
        $lt: ISODate(some other time)
    }
}).length

查看更多不同的用例,而不是很多人都知道这种方法。

答案 1 :(得分:0)

这是怎么回事?

db.your_collection.aggregate([{'$project': {'_id': {'yymmdd': {'$dateToString': {'date': '$_systemTime', 'format': '%Y-%m-%d'}}, 'user': '$_user'}}}, {'$group': {'count': {'$sum': 1}, '_id': '$_id'}}])

(*)可能是您想要在管道的开头输入$ match range clouse,如果您只需要将其限制在某些日期。

答案 2 :(得分:0)

所以,如果我说得对,你想要那些日子里访问过的不同用户吗?

db.collection.aggregate(
  { $match: 
    { "_systemTime": 
      {
        $gte: ISODate("2015-03-21T00:00:00"),
        $lt: ISODate("2015-03-23T00:00:00")
      }
    }
  },
  { $group:
    {
      _id: { "_user":"$_user", day: { $dayOfMonth: "$_systemTime" } },
      visits: { $sum: 1 }
    }
  },
  { $out: "usersPerDay"}
)

但是,这种聚合只有在你向$group阶段添加一些东西时才有意义,例如访问次数,例如。

现在,您可以查询usersPerDay以获取所需信息:

db.usersPerDay.find({"_id.day":21}).count()

当您调整上面显示的聚合的$group阶段时,聚合应该能够为您提供基本上任何时基统计。