MongoDB C# 使用 LINQ 进行聚合操作

7

我有一个Mongo对象,包含以下字段:

DateTime TimeStamp;
float    Value;

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

我已经看过一些聚合示例,但是我还不太理解。如果能有一个简单案例的示例,那肯定会让我更容易理解。

2个回答

8
你可以使用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驱动程序支持的累加器列表可以在此处找到:这里
编辑:需要使用(Model)null,因为查询必须转换为$group,并将_id设置为null (文档),因为您想要使用聚合函数获取一个结果。强制转换只是为了C#编译器的目的,因为doc的类型是Model

你能解释一下 '(Model) null' 部分吗?我不明白那里的 null 关键字是什么意思。 - Thomas
另外一个问题:在where下面是否可以做一些类似于let Value = doc.Value的操作,然后将Value分组,以便不必携带对象的其余部分? - Thomas
@Thomas 在我的编辑答案中解释了 null 部分。你可以在这里阅读更多关于支持哪些 LINQ 操作符的信息(http://mongodb.github.io/mongo-csharp-driver/2.7/reference/driver/crud/linq/)。 - mickl

3
这个聚合过程分为两步:
  1. $match - 检索时间戳 TimeStamp 值介于某个定义的minDatemaxDate之间的文档。
  2. $group - 以空值进行分组。这将把所有文档放在一个组中,这样我们就可以在第一步$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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接