繁体   English   中英

MongoDB 聚合/组 -> 按日期获取单个活跃用户的数量

[英]MongoDB aggregate/group -> get amount of single active users by date

我正在尝试汇总保存的用户会话并获取日期范围内每个日期的单个活跃访问者的数量。

我有一个 session model 包含以下属性:

{
  'environment' : ObjectId("xxxxxxxxxxxxxxxxxxxxxxxx"),
  'created'     : ISODate("2021-01-05T22:02:25.757Z"),
  'visitor'     : ObjectId("xxxxxxxxxxxxxxxxxxxxxxxx")
}

结果应如下所示:

[
  {
    'date'  : '2021-01-03',
    'count' : 5 // this is the amount of unique visitors. If there are two documents with the same date and visitor id, only one should be count.
  },
  {
    'date'  : '2021-01-05',
    'count' : 15 
  },
  {
    'date'  : '2021-01-06',
    'count' : 11
  },
  ...etc...
]

这是我尝试的最后一个管道,当然这是错误的:

const data = await Session.aggregate([
  {
    '$match': {
       environment : ObjectID( args.environment ),
       created     : { '$gte': new Date( args.start ), '$lte': new Date( args.end ) }
    }
  },
  {
    $addFields:{
      createdDate:{
        $dateFromParts:{
          year:{
            $year:"$created"
          }, 
          month:{
            $month:"$created"
          }, 
          day:{
            $dayOfMonth : "$created" 
          }
        }
      }
    }
  },
  {
    $group:{
      _id:{
        date:"$createdDate",visitor:"$visitor"
      },
      count:{$sum:1}
    }
  },
  {
    $project:{
      _id:0,
      date:"$_id.date",
      count:"$count",
    }
  }
])

我为我的管道尝试了一些我自己的组合和一些 SO 组合,但还没有取得很大的成功。

帮助将不胜感激。

我认为您正在搜索的是$addToSet运算符。

返回一个由所有唯一值组成的数组,这些唯一值是通过将表达式应用于一组文档中的每个文档而产生的,这些文档按键共享同一组。

文档: https://docs.mongodb.com/manual/reference/operator/aggregation/addToSet/

您只需要按天分组并将访问者 ID 添加到集合中,如果存在则不添加,如果不存在则不添加,然后 kaboom。 之后,您只需要计算该列表中有多少元素。

const data = await Session.aggregate([
  {
    $match: {
      environment : ObjectID( args.environment ),
      created     : { '$gte': new Date( args.start ), '$lte': new Date( args.end ) }
    }
  },
  {
    $group: {
      _id: {
        $dateToString: {
          format : "%Y-%m-%d",
          date   : "$created"
        },
      },
      visitors: { $addToSet: "$visitor" }
    }
  },
  {
    $project: {
      _id: 0,
      date: "$_id",
      count: { $size: "$visitors" }
    }
  }
])

您可以将项目阶段与 $dateToString 一起使用,此外,它还允许在需要时指定时区

 const data = await Session.aggregate([
  {
    '$match': {
       environment : ObjectID( args.environment ),
       created     : { '$gte': new Date( args.start ), '$lte': new Date( args.end ) }
    }
  },
  {
    $project:{
      visitor: 1,
      createdDate: { $dateToString: { format: "%Y-%m-%d", date: "$created" } },
    }
  },
  {
    $group:{
      _id:{
        date:"$createdDate",visitor:"$visitor"
      },
      count:{$sum:1}
    }
  },
  {
    $project:{
      _id:0,
      date:"$_id.date",
      count:"$count",
    }
  }
])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM