簡體   English   中英

如何在C#中使用linq / mongodb平均非空值

[英]How to average non null values with linq / mongodb in c#

我有一個帶有對象的表,該對象具有用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的對象

簡單的解決方案是使用可為空的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")
        }
    }
])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM