我有一个表,其中对象的字段标记为 BsonIgnoreIfDefault 。
反序列化对象时,字段显示为空。
我正在尝试对使用AsQueryable()解析的集合进行平均。
查询如下:
var Result = db.Collection.AsQueryable()
.Where(_ => _.TimeStamp >= From && _.TimeStamp < To)
.GroupBy(_ => true) // not sure why, but I can't compile without this
.Select(_ => new
{
R = new Result
{
TimeStamp = From,
i = _.Average(P => P.i)
},
Count = _.Count()
}
).FirstOrDefault();
,但是有时 i 字段为空。这样进行平均时如何跳过空值?
对象就像
class A
{
public DateTime TimeStamp;
[BsonIgnoreIfDefault]
public double i;
}
此外,我发现反序列化时,对象不能保持空;所以我想找到如何仅对具有 i
属性的对象求平均答案 0 :(得分:-1)
简单的解决方案是使用可为空的double属性double?
。这是产生预期结果的完整解决方案。
using MongoDB.Entities;
using System;
using System.Linq;
namespace StackOverflow
{
public class Program
{
public class Record : Entity
{
public DateTime TimeStamp { get; set; }
public double? Value { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
(new[] {
new Record { TimeStamp = DateTime.UtcNow },
new Record { TimeStamp = DateTime.UtcNow, Value = null },
new Record { TimeStamp = DateTime.UtcNow, Value = 2 },
new Record { TimeStamp = DateTime.UtcNow, Value = 2 }
}).Save();
var from = DateTime.UtcNow.AddMinutes(-1);
var to = DateTime.UtcNow.AddMinutes(1);
var result = DB.Queryable<Record>()
.Where(r => r.Value != null && r.TimeStamp >= from && r.TimeStamp <= to)
.GroupBy(r => true)
.Select(g => new
{
Rec = new Record { TimeStamp = from, Value = g.Average(r => r.Value) },
Count = g.Count()
})
.Single();
Console.WriteLine($"Average: {result.Rec.Value}");
Console.WriteLine($"Count: {result.Count}");
Console.ReadKey();
}
}
}
上面使用的是我的库 MongoDB.Entities ,但查询部分与官方驱动程序的.AsQueryable
相同。
它将产生以下聚合查询:
db.Record.aggregate([
{
"$match": {
"Value": {
"$ne": null
},
"TimeStamp": {
"$gte": ISODate("2019-06-30T07:20:59.126Z"),
"$lte": ISODate("2019-06-30T07:22:59.126Z")
}
}
},
{
"$group": {
"_id": true,
"__agg0": {
"$avg": "$Value"
},
"__agg1": {
"$sum": NumberInt("1")
}
}
},
{
"$project": {
"Rec": {
"TimeStamp": ISODate("2019-06-30T07:20:59.126Z"),
"Value": "$__agg0"
},
"Count": "$__agg1",
"_id": NumberInt("0")
}
}
])