2017-01-14 2 views
0

Использование драйвера C# MongoDb.Данные группы по датам

У меня есть коллекция входов, в которой хранятся последние логины системы.

Я хотел бы сгруппировать их по 2 группам: последние 24 часа и последний час.

Объект выглядит следующим образом:

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

Каждый пользователь, как вы можете вычесть, имеет только один ряд.

Ожидаемый результат будет выглядеть примерно так:

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

У меня нет опыта работы с агрегирование и все примера Ive видели на вики были на группируя общие поля, здесь у меня есть манипуляции с данными, так что я не имею инструменты.

Было бы неплохо, если я смогу использовать AggregateAsync вместо Aggregate.

ответ

1

Мне удалось это сделать с помощью структуры агрегации. То, что я не мог сделать, это преобразовать флаг bool, если логин был в течение 24 часов, чтобы назвать его, я сделал это с дополнительным Select.

Сначала мы получаем все логины в течение последних 24 часов, чем мы группируем результаты в зависимости от того, были ли они в последний час или нет (true/false), после чего мы получаем весь результат как перечислимый и совершенный тонкий настрой на имя, i описал ранее.

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

можно использовать проекцию и gtoup в C# как это:

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; 
Смежные вопросы