Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
544 views
in Technique[技术] by (71.8m points)

c# - MongoDB.Driver.Builders how to group and get average

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.

This code shows how the group is made with BSON documents, but we find that synthax not clear to read and very confusing ! So were are looking for the correct builder synthax.

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);

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...