MongoDB.Driver.Builders 如何分组并取平均值 [英] MongoDB.Driver.Builders how to group and get average

查看:18
本文介绍了MongoDB.Driver.Builders 如何分组并取平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用 C# MongoDB 驱动程序,我们希望对时间戳的日期部分进行分组并获取该日期的平均值.问题是我们无法使用构建器为组找到正确的合成器.

We are using the C# MongoDB driver, and we would like to group on the Date part of a timestamp and get the average for that date. The problem is that we can't find the correct synthax for the group using the builders.

这段代码显示了如何使用 BSON 文档创建组,但我们发现合成器读起来不清晰而且非常混乱!因此正在寻找正确的构建器合成器.

我们希望使用 Builders,因为它在 C# 中的类型更多,然后在管道中使用带有 BsonDocuments 的方法.这是一个代码片段,前 3 个操作在其中起作用,但我们找不到 GroupBy.

We would like to use the Builders because it is more typed in C# then using the method with BsonDocuments in a pipeline. Here is a code snippet, where the first 3 operations work, but we can't find out GroupBy.

        DateTime from = new DateTime(2014, 12, 2);
        DateTime to = new DateTime(2014, 12, 4);
        var id = "37d163c0-44cc-4907-94cf-1e26b5eec911";

        var grp = new BsonDocument
        {
            {
                //Sort the documents into groups
                "$group",
                new BsonDocument
                {
                    //Make the unique identifier for the group a BSON element consisting
                    // of a field named Car.
                    // Set its value to that of the Cars field
                    // The Cars field is nolonger an array because it has now been unwound
                    //{ "_id", new BsonDocument { { "Date", "$Date" } }  },
                    {
                        "_id",new BsonDocument{ new BsonDocument("year",new BsonDocument ("$year","$Date")),
                                new BsonDocument("month",new BsonDocument ("$month","$Date")),
                                new BsonDocument("day",new BsonDocument ("$dayOfMonth","$Date"))
                                }
                    },
                    {
                        //Add a field named Owners
                        "avgAmount",
                        new BsonDocument
                        {
                            { "$avg" ,"$Value"}
                       }
                   }
                }
            }
        };

        AggregateArgs aggregateArgs = new AggregateArgs()
        {
            Pipeline = new[]
        {
            new BsonDocument("$match", Query<Reading>.EQ(c => c.SensorId, id).ToBsonDocument())
            , new BsonDocument("$match", Query<Reading>.LTE(c => c.Date, to).ToBsonDocument())
            , new BsonDocument("$match", Query<Reading>.GTE(c => c.Date, from).ToBsonDocument())
            , grp
            //, new BsonDocument("$group",GroupBy<Reading>.Keys(c=> c.Date).ToBsonDocument())


        }
        };
        IEnumerable<BsonDocument> documents = collection.Aggregate(aggregateArgs);

感谢所有帮助,我们已经查看了论坛上的类似问题,但找不到正确的工作解决方案,问题 1问题 2.

All help is appreciated, we already looked in simular questions on the forum, but can't find a correct working solution, question 1 or question 2.

推荐答案

使用新的 MongoDB .NET 驱动程序 (2.0 - http://docs.mongodb.org/ecosystem/drivers/csharp/) ,完全支持 Linq 支持,这里是使用新驱动程序的问题的合成器..NET 代码比使用 BsonDocument 合成器之前更易读.

with the new MongoDB .NET driver (2.0 - http://docs.mongodb.org/ecosystem/drivers/csharp/) , Linq support is fully suported, here is the synthax of the question usign the new driver. Much more readable .NET code then before using the BsonDocument synthax.

    public async Task<List<DailyStat>> GetLast31DaysReport(string id)
    {
        var mc = new MongoClient(_url);
        var db = mc.GetDatabase(DbName);
        var collection = db.GetCollection<Reading>(CollectionName);

        DateTime from = DateTime.Now.AddDays(-31);
        DateTime to = DateTime.Now;

        var output = await collection.Aggregate()
            .Match(r => r.SensorId == id)
            .Match(r => r.Date <= to)
            .Match(r => r.Date >= to.AddDays(-31))
            .Group(r => new { groupedYear = r.Date.Year, groupedMonth = r.Date.Month, groupedDay = r.Date.Day }, g =>
                new {
                    Key = g.Key,
                    avgValue = g.Average(x => x.Value),
                    minValue = g.Min(x => x.Value),
                    maxValue = g.Max(x => x.Value)
                })
            .Project(r => new DailyStat()
                {
                    Day = r.Key.groupedDay,
                    Month = r.Key.groupedMonth,
                    Year = r.Key.groupedYear,
                    Value = r.avgValue,
                    MinValue = r.minValue,
                    MaxValue = r.maxValue
                })
            .ToListAsync().ConfigureAwait(false);

        var returnList = new List<DailyStat>();
        while (returnList.Count < 31)
        {
            var value = output.FirstOrDefault(rec => rec.Day == from.Day && rec.Month == from.Month && rec.Year == from.Year);
            returnList.Add(value ?? new DailyStat() { Month = from.Month, Year = from.Year, Day = from.Day, Value = 0, MaxValue = 0, MinValue = 0 });
            from = from.AddDays(1);
        }
        return returnList;
    }

这篇关于MongoDB.Driver.Builders 如何分组并取平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆