使用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
,那就太好了。
答案 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;