【问题标题】:Group data by dates按日期分组数据
【发布时间】:2017-01-14 15:11:07
【问题描述】:

使用 C# MongoDb 驱动程序。

我有一个登录集合,用于存储系统的最后一次登录。

我想将它们分成两组:过去 24 小时和最后一小时。

对象看起来像这样:

public sealed class Login
{
    [BsonId]
    public ObjectId UserId;
    public DateTime LastLogin;
}

您可以推断,每个用户只有 1 行。

预期的结果类似于:

{
"Id" : "24Hours", "Count" : <some number>,
"Id" : "LastHour", "Count" : <some other number>
}

我没有聚合经验,我在 Wiki 上看到的所有示例都是关于对公共字段进行分组的,这里我有数据操作,所以我没有工具。

如果我能够使用AggregateAsync 而不是Aggregate,那就太好了。

【问题讨论】:

    标签: c# mongodb aggregation-framework mongodb-.net-driver


    【解决方案1】:

    我已经设法通过聚合框架做到了这一点。我不能做的是转换布尔标志,如果登录是在 24 小时内命名,我用额外的Select 做到了。

    首先,我们在过去 24 小时内获得所有登录信息,然后根据结果是在过去一小时内还是非(真/假)对结果进行分组,之后我们将整个结果作为可枚举并对名称进行微调,我有之前描述过。

    var result =
        collection.Aggregate()
           .Match(x => x.LastLogin >= DateTime.Now.AddDays(-1) && x.LastLogin <= DateTime.Now)
           .Group(r => r.LastLogin <= DateTime.Now.AddHours(-1), r =>
                           new { WithinLastHour = r.Key ,  Count = r.Count()})
           .ToEnumerable()
           .Select(x=>
                    new {Name = x.WithinLastHour ? "Within last hour":"Within last 24 hours", 
                         x.Count})
           .ToList();
    

    当然,如果你愿意,你可以使用AggregateAsync

    【讨论】:

      【解决方案2】:

      我可以像这样在 c# 中使用投影和 gtoup:

      var yesterday = DateTime.Now.AddDays(-1);
      var lastHour = DateTime.Now.AddHours(-1);
      
      var projection = new BsonDocument
      {
          {
              "Last24Hours",
              new BsonDocument("$cond",
                  new BsonArray {new BsonDocument("$gte", new BsonArray {"$LastLogin", yesterday}), 1, 0})
          },
          {
              "LastHour",
              new BsonDocument("$cond",
                  new BsonArray {new BsonDocument("$gte", new BsonArray {"$LastLogin", lastHour}), 1, 0})
          }
      };
      
      var groupBy = new BsonDocument
      {
          {"_id", BsonNull.Value},
          {"CountLast24Hours", new BsonDocument("$sum", "$Last24Hours")},
          {"CountLastHour", new BsonDocument("$sum", "$LastHour")}
      };
      

      并通过使用这样的管道获得结果:

      var pipeline = PipelineDefinition<Login, BsonDocument>.Create(
          new BsonDocument("$project", projection),
          new BsonDocument("$group", groupBy), 
          );
      var result = col.Aggregate(pipeline).SingleOrDefault();
      
      var countLast24Hours = result["CountLast24Hours"].AsInt32;
      var countLastHour = result["CountLastHour"].AsInt32;
      

      【讨论】:

        猜你喜欢
        • 2021-03-09
        • 1970-01-01
        • 2016-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-19
        • 2017-01-16
        相关资源
        最近更新 更多