MongoDB计算每个用户的天数

MongoDB计算每个用户的天数,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我试图创建一个查询,计算用户在一个月内完成一项操作的次数 这是数据格式: [ { "happened": ISODate(2017-1-1), "user": ObjectId(a), "action": ObjectId(i) }, { "happened": ISODate(2017-1-1), "user": ObjectId(a), "action": ObjectId(i) } ] 我想知道一个用户在一段时间内做了多少次

我试图创建一个查询,计算用户在一个月内完成一项操作的次数

这是数据格式:

[
  {
    "happened": ISODate(2017-1-1),
    "user": ObjectId(a),
    "action": ObjectId(i)
  },
  {
    "happened": ISODate(2017-1-1),
    "user": ObjectId(a),
    "action": ObjectId(i)
  }
]
我想知道一个用户在一段时间内做了多少次某个动作

我已经找到了
$match

{
  $match: {
    happened: { $gte: 2017-1-1, $lt: 2017-2-1 },
    action: i
  }
}
我也一直在试验
$group
位,但我不知道如何得到我想要的。这就是我到目前为止所做的:

{
  $group: {
    _id: {
      user: "$user",
      year: { $year: "$happened" },
      day: { $dayOfYear: "$happened" }
    },
    count: { $sum: 1 }
  }
}
我想看看每个用户执行操作的天数。但我无法超越这一点:

[
  {
    "_id": {
      "user": ObjectId(a),
      "year": ObjectId(2017),
      "day": ObjectId(1)
    },
    "count": 1
  },
  {
    "_id": {
      "user": ObjectId(a),
      "year": ObjectId(2017),
      "day": ObjectId(2)
    },
    "count": 1
  }
]
您可以看到,我正在获取每个用户的实例数,但它也显示了每天的实例数。我想查看每个用户的天数。

您可以将根文档添加到一个临时数组中,然后再次创建一个组,使用前一个计算天数的第一个值:

db.data.aggregate([{
    $match: {
        happened: { $gte: ISODate("2017-01-01"), $lt: ISODate("2017-02-01") },
        action: "Action1"
    }
}, {
    $group: {
        _id: {
            day: { $dayOfMonth: "$happened" }
        },
        dayCount: { $sum: 1 },
        doc: { $push: "$$ROOT" }
    }
}, {
    $unwind: "$doc"
}, {
    $group: {
        _id: "$doc.user",
        dayCount: { $first: "$dayCount" },
        actionCount: { $sum: 1 }
    }
}])
它为您提供userId、dayCount(至少执行一个操作的天数)和actionCount:

{ "_id" : "1", "dayCount" : 2, "actionCount" : 2 }
{ "_id" : "2", "dayCount" : 3, "actionCount" : 4 }
您可以将根文档添加到临时数组中,然后再次创建一个组,以获取上一计算天数的第一个值:

db.data.aggregate([{
    $match: {
        happened: { $gte: ISODate("2017-01-01"), $lt: ISODate("2017-02-01") },
        action: "Action1"
    }
}, {
    $group: {
        _id: {
            day: { $dayOfMonth: "$happened" }
        },
        dayCount: { $sum: 1 },
        doc: { $push: "$$ROOT" }
    }
}, {
    $unwind: "$doc"
}, {
    $group: {
        _id: "$doc.user",
        dayCount: { $first: "$dayCount" },
        actionCount: { $sum: 1 }
    }
}])
它为您提供userId、dayCount(至少执行一个操作的天数)和actionCount:

{ "_id" : "1", "dayCount" : 2, "actionCount" : 2 }
{ "_id" : "2", "dayCount" : 3, "actionCount" : 4 }

你可以试试下面的聚合

首先
$group
为每个用户获取不同的天数,然后
$group
$push
获取不同的天数,然后
$project
计算天数

{ $group: { _id: { user: "$user", day: { $dayOfMonth: "$happened" } } } },
{ $group: { _id: "_id.$user", days:{$push:"$_id.day"} } },
{ $project: { user:"$user", count: { $size: "$days" } } }

你可以试试下面的聚合

首先
$group
为每个用户获取不同的天数,然后
$group
$push
获取不同的天数,然后
$project
计算天数

{ $group: { _id: { user: "$user", day: { $dayOfMonth: "$happened" } } } },
{ $group: { _id: "_id.$user", days:{$push:"$_id.day"} } },
{ $project: { user:"$user", count: { $size: "$days" } } }


每个文档都有每个用户的操作日期。你只要数一数就行了。类似这样的
{$group:{{user:{$user:{$user},count:{$sum:1}}}
问题是,如果他们在周一执行一次操作,在周二执行两次操作(计数为3),我试图将其计数为2,成员/操作每天计数一次。每个文档都有每个用户的操作日期。你只要数一数就行了。类似这样的
{$group:{{user:{$user:{$user},count:{$sum:1}}}
问题是,如果他们在周一执行一次操作,在周二执行两次操作,计数为3,我试图将其计数为2,成员/操作每天计数一次。这将返回一个关于$push的错误。{[MongoError:invalid operator'$push']name:'MongoError',message:'invalid operator\'$push\'',ok:0,errmsg:'invalid operator\'$push\'',code:15999}您的mongodb版本是什么?Mongo版本:3.2.6(Thx供您帮助:D)您正在使用mongodb shell吗?你能试试看它是否运行吗?它使用的是猫鼬,但即使在3.4.2上,它也在运行。不过,您的示例在shell中确实有效。可能是猫鼬的问题,也就是说Veeram的代码可以工作,但我还不能进行排序。这会返回一个关于$push的错误。{[MongoError:invalid operator'$push']name:'MongoError',message:'invalid operator\'$push\'',ok:0,errmsg:'invalid operator\'$push\'',code:15999}您的mongodb版本是什么?Mongo版本:3.2.6(Thx供您帮助:D)您正在使用mongodb shell吗?你能试试看它是否运行吗?它使用的是猫鼬,但即使在3.4.2上,它也在运行。不过,您的示例在shell中确实有效。可能是猫鼬的问题,也就是说Veeram的代码可以工作,但我还不能进行排序。这很有效,但是添加
$sort:[{count:-1}]
没有效果
$sort:{count:-1}
就是这样,猫鼬对猫鼬…:(这是有效的,但是添加
$sort:[{count:-1}]
没有效果
$sort:{count:-1}
就是这样,Mongoose对Mongo…:(