MongoDB C # Агрегация с помощью LINQ - PullRequest
0 голосов
/ 28 августа 2018

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

DateTime TimeStamp;
float    Value;

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

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Вы можете использовать синтаксис 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, можно найти здесь .

РЕДАКТИРОВАТЬ: (Model)null требуется, потому что запрос должен быть преобразован в $group с _id, установленным в null ( docs ), так как вы хотите получить один результат с агрегатами. Приведение требуется только для целей компилятора C #, поскольку документ имеет тип Model.

0 голосов
/ 28 августа 2018

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

  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;
...