按日期分组数据

时间:2017-01-14 15:11:08

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

使用C#MongoDb驱动程序。

我有一个Login集合,它存储了系统的最后一次登录。

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

对象看起来像这样:

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

您可以扣除的每个用户只有一行。

预期结果如下:

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

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

如果我能够使用AggregateAsync代替Aggregate,那就太好了。

2 个答案:

答案 0 :(得分:1)

我已成功使用Aggregation框架。我不能做的是转换bool标志,如果登录在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

答案 1 :(得分:1)

我可以在c#中使用projection和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;