Агрегация MongoDB C# с LINQ



У меня есть объект mongo с этими полями:



DateTime TimeStamp;
float Value;


Как я могу получить конвейер агрегации в C# с помощью LINQ, чтобы получить минимальное, максимальное и среднее значение в определенном диапазоне временных меток?



Я видел несколько примеров агрегации, но я не совсем понимаю это. Имея пример в таком простом случае, как этот, безусловно (надеюсь) заставит меня понять его.
766   2  

2 ответов:

Вы можете использовать синтаксис LINQ, который переводится в синтаксис Aggregation Framework. Предположим, что у вас есть следующий класс Model:

public class Model
{
    public DateTime Timestamp { get; set; }
    public float Value { get; set; }
}

Вы можете использовать where для указания диапазона временных меток, а затем использовать group с null в качестве ключа группировки. MongoDB драйвер переведет Min, Max и Average из анонимного типа в $max, $min и $avg из синтаксиса Aggregation Framework

var q = from doc in Col.AsQueryable()
        where doc.Timestamp > DateTime.Now.AddDays(-3)
        where doc.Timestamp < DateTime.Now.AddDays(3)
        group doc by (Model)null into gr
        select new
        {
            Avg = (double)gr.Average(x => x.Value),
            Min = gr.Min(x => x.Value),
            Max = gr.Max(x => x.Value)
        };

var result = q.First();

Список аккумуляторов, поддерживаемых драйвером MongoDB, можно найти здесь .

EDIT: (Model)null требуется, поскольку запрос должен быть преобразован в $group С _id, установленным в null (docs ), так как вы хотите получить один результат с агрегатами. Приведение требуется только для компилятора C#, так как doc имеет тип Model.

Агрегирование для этого выполняется в два этапа:

  1. $match - извлекает документы со значением TimeStamp между некоторыми определенными minDate и maxDate.
  2. $group - Группа на нуле. Это поместит все документы в одну группу, так что мы сможем применить функцию аккумулятора ко всему, начиная с шага 1 $match. Функции аккумулятора, которые вы ищете, являются $min, $max, и $avg.

IMongoCollection<Entity> collection = GetMyCollection();

DateTime minDate = default(DateTime); // define this yourself
DateTime maxDate = default(DateTime); // define this yourself

var match = new BsonDocument
{ {
    "$match", new BsonDocument
    { {
        "TimeStamp", new BsonDocument
        { {
            "$and", new BsonDocument
            {
                { "$gt", minDate },
                { "$lt", maxDate }
            }
        } }
    } }
} };

var group = new BsonDocument
{ {
    "$group", new BsonDocument
    {
        { "_id", BsonNull.Value },
        { "min", new BsonDocument { { "$min", "Value" } } },
        { "max", new BsonDocument { { "$max", "Value" } } },
        { "avg", new BsonDocument { { "$avg", "Value" } } },
    }
} };

var result = collection.Aggregate(PipelineDefinition<Entity, BsonDocument>.Create(match, group)).Single();

double min = result["min"].AsDouble;
double max = result["max"].AsDouble;
double avg = result["avg"].AsDouble;

Comments

    Ничего не найдено.