MongoDB 使用 LINQ 的 C# 聚合
MongoDB C# Aggregation with LINQ
我有一个包含这些字段的 mongo 对象:
DateTime TimeStamp;
float Value;
如何在 C# 中使用 LINQ 获取聚合管道,以获取特定时间戳范围内的最小值、最大值和平均值?
我看过一些聚合示例,但我不太明白。有一个像这样的简单案例的例子肯定(希望)让我理解它。
此聚合分两步完成:
$match
- 检索 TimeStamp
值介于某些定义的 minDate
和 maxDate
. 之间的文档
$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;
您可以使用转换为聚合框架语法的 LINQ 语法。假设您有以下 Model
class:
public class Model
{
public DateTime Timestamp { get; set; }
public float Value { get; set; }
}
您可以使用 where
指定时间戳范围,然后使用 group
和 null
作为分组键。 MongoDB 驱动程序会将匿名类型的 Min
、Max
和 Average
转换为聚合框架语法中的 $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# 编译器需要强制转换
我有一个包含这些字段的 mongo 对象:
DateTime TimeStamp;
float Value;
如何在 C# 中使用 LINQ 获取聚合管道,以获取特定时间戳范围内的最小值、最大值和平均值?
我看过一些聚合示例,但我不太明白。有一个像这样的简单案例的例子肯定(希望)让我理解它。
此聚合分两步完成:
$match
- 检索TimeStamp
值介于某些定义的minDate
和maxDate
. 之间的文档
$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;
您可以使用转换为聚合框架语法的 LINQ 语法。假设您有以下 Model
class:
public class Model
{
public DateTime Timestamp { get; set; }
public float Value { get; set; }
}
您可以使用 where
指定时间戳范围,然后使用 group
和 null
作为分组键。 MongoDB 驱动程序会将匿名类型的 Min
、Max
和 Average
转换为聚合框架语法中的 $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
.