MongoDB C# Aggregation with LINQ MongoDB C# Aggregation with LINQ mongodb mongodb

MongoDB C# Aggregation with LINQ


You can use LINQ syntax which gets translated into Aggregation Framework's syntax. Assuming you have following Model class:

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

you can use where to specify timestamp range and then use group with null as grouping key. MongoDB driver will translate Min, Max and Average from anonymous type into $max, $min and $avg from Aggregation Framework syntax

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();

List of accumulators supported by MongoDB driver can be found here.

EDIT: the (Model)null is required because the query has to be transformed to $group with _id set to null (docs) since you want to get one result with aggregates. Casting is required just for C# compiler purpose as doc is of type Model.


The aggregation for this is done in two steps:

  1. $match - Retrieve documents with TimeStamp value between some defined minDate and maxDate.
  2. $group - Group on null. This will put all documents in a single group so we can apply an accumulator function across everything from the step 1 $match. The accumulator functions you're looking for are $min, $max, and $avg.

IMongoCollection<Entity> collection = GetMyCollection();DateTime minDate = default(DateTime); // define this yourselfDateTime maxDate = default(DateTime); // define this yourselfvar 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;