【问题标题】:c# and mongodb: Aggregates with filterc# 和 mongodb:使用过滤器聚合
【发布时间】:2017-08-23 10:01:39
【问题描述】:

我正在使用最新版本的 mongodb 和 C# 的 MongoDB 驱动程序。我创建了一个小例子,应该可以解释我的问题。我的目标是用过滤器制作一些条件 Count()、条件 First() 或 Average()。都不行。

这个问题的最佳解决方案是什么。感谢您的任何提示

    class MealDocument
    {
        public string name { get; set; }
        public DateTime time { get; set; }
        public Type type { get; set; }
        public double calorie { get; set; }
        public enum Type { breakfast, launch, dinner }
    }

    class MealAnalysis
    {
        public string name { get; set; }
        public int numberOfBreakfast { get; set; }
        public DateTime firstLaunch { get; set; }
        public double averageDinnerCalorie { get; set; }
    }

    public void Test()
    {
        var collection = Database.GetCollection<MealDocument>("meal_test");

        collection.InsertMany(new MealDocument[] {
            new MealDocument { name = "Thomas", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,1) },
            new MealDocument { name = "Thomas", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,2) },
            new MealDocument { name = "Thomas", type = MealDocument.Type.launch, calorie = 800, time = new DateTime(2017,8,3) },
            new MealDocument { name = "Thomas", type = MealDocument.Type.dinner, calorie = 2000, time = new DateTime(2017,8,4) },
            new MealDocument { name = "Peter", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,5) },
            new MealDocument { name = "Peter", type = MealDocument.Type.launch, calorie = 500, time = new DateTime(2017,8,6) },
            new MealDocument { name = "Peter", type = MealDocument.Type.dinner, calorie = 800, time = new DateTime(2017,8,7) },
            new MealDocument { name = "Paul", type = MealDocument.Type.breakfast, calorie = 200, time = new DateTime(2017,8,8) },
            new MealDocument { name = "Paul", type = MealDocument.Type.launch, calorie = 600, time = new DateTime(2017,8,9) },
            new MealDocument { name = "Paul", type = MealDocument.Type.launch, calorie = 700, time = new DateTime(2017,8,10) },
            new MealDocument { name = "Paul", type = MealDocument.Type.dinner, calorie = 1200, time = new DateTime(2017,8,11) }
        });

        var analysis = collection.Aggregate()
            .Group(
                doc => doc.name,
                group => new MealAnalysis
                {
                    name = group.Key,

                    // !!!! The condition in the Count() gets ignored
                    numberOfBreakfast = group.Count(m => m.type == MealDocument.Type.breakfast),

                    // !!!! Exception --> Not supported
                    averageDinnerCalorie = group.Where(m => m.type == MealDocument.Type.dinner).Average(m => m.calorie),

                    // !!!! Exception --> Not supported
                    firstLaunch = group.First(m => m.type == MealDocument.Type.launch).time
                }
            );

        var query = analysis.ToString();

        var result = analysis.ToList();
    }

【问题讨论】:

标签: c# mongodb linq aggregate


【解决方案1】:

我花了几个小时,我无法让司机按您的需要工作。虽然我没有想出正确的解决方案,但这是我得到的最接近的解决方案。我不是这个解决方案的忠实拥护者,因为它计算了很多你不需要的东西,但是如果 Db 不是那么大并且在你找到问题的解决方案之前它可能会工作得很好。

var groupRes = collection.Aggregate()
                .Group
                    (
                        x => new { x.name, x.type },
                        g => new
                        {
                            key = g.Key,
                            count = g.Count(),
                            averageCalorie = g.Average(y => y.calorie),
                            first = g.First().time
                        }
                    )
                .ToList();
            var paulStat = new MealAnalysis()
            {
                name = "Paul",
                averageDinnerCalorie = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.dinner)).averageCalorie,
                numberOfBreakfast = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.breakfast)).count,
                firstLaunch = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.launch)).first
            };

如您所见,我计算了每个枚举所需的内容,然后为每个人构造了他的MealAnalysis。也许有人找到了您需要的解决方案。

祝你好运!

【讨论】:

  • 感谢您花这么多时间。如果我发现更多,我会报告
  • 没问题,请做。我对我们在这里缺少的东西非常感兴趣。
猜你喜欢
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 2019-03-13
  • 1970-01-01
  • 2021-07-26
  • 2021-11-18
  • 1970-01-01
  • 2020-04-14
相关资源
最近更新 更多