【问题标题】:MongoDB C# Aggregation with LINQ使用 LINQ 进行 MongoDB C# 聚合
【发布时间】:2019-02-03 12:50:44
【问题描述】:

我有一个带有这些字段的 mongo 对象:

DateTime TimeStamp;
float    Value;

如何在 C# 中使用 LINQ 获取聚合管道,以获取特定时间戳范围内 Value 的最小值、最大值和平均值?

我看过一些聚合示例,但我不太明白。有一个像这样的简单案例的例子肯定会(希望)让我理解它。

【问题讨论】:

    标签: c# mongodb aggregation


    【解决方案1】:

    您可以使用翻译成聚合框架语法的 LINQ 语法。假设您有以下 Model 类:

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

    您可以使用where 指定时间戳范围,然后使用groupnull 作为分组键。 MongoDB 驱动程序会将 MinMaxAverage 从匿名类型转换为来自聚合框架语法的 $max$min$avg

    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驱动支持的累加器列表见here

    编辑:(Model)null 是必需的,因为必须将查询转换为 $group 并将 _id 设置为 null (docs),因为您想获得一个聚合结果。由于 doc 的类型为 Model,因此仅出于 C# 编译器的目的需要强制转换。

    【讨论】:

    • 你能解释一下'(Model) null'部分吗?我不明白那里的 null 关键字
    • 一个额外的问题:是否可以在 where 下方做某事,例如:让 Value = doc.Value 然后对 Value 进行分组,以便不携带对象的其余部分?
    • @Thomas 在我编辑的答案中解释了 null 部分。您可以在此处 (mongodb.github.io/mongo-csharp-driver/2.7/reference/driver/crud/…) 阅读有关支持哪些 LINQ 运算符的更多信息
    【解决方案2】:

    对此的聚合分两步完成:

    1. $match - 检索 TimeStamp 值介于某些定义的 minDatemaxDate 之间的文档。
    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 2019-06-29
      • 2017-02-16
      • 2018-03-27
      相关资源
      最近更新 更多