2017-08-23 3 views
0

J'utilise la dernière version de mongodb avec le pilote MongoDB pour C#. J'ai créé un petit exemple, ce qui devrait expliquer mon problème. Mon but est de faire un peu de conditionnel(), conditionnel() ou moyen() avec un filtre. Rien ne fonctionne.C# et mongodb: Agrégats avec filtre

Quelle serait la meilleure solution à ce problème. Merci pour toute allusion

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(); 
    } 
+0

Je vais vous aider sur mon ** déjeuner ** pause =). Il vous manque une partie du projet. Peut-être que ce post vous aide https://stackoverflow.com/questions/27315852/mongodb-driver-builders-how-to-group-and-get-average. Je reviendrai à vous dans quelques heures. – BOR4

Répondre

0

J'ai passé quelques heures et je ne peux pas obtenir le conducteur pour travailler comme vous en avez besoin. Même si je n'ai pas trouvé la bonne solution, c'est ce que j'ai trouvé le plus proche. Je ne suis pas un grand fan de cette solution, car elle calcule beaucoup de choses dont vous n'avez pas besoin, mais cela pourrait bien fonctionner si Db n'est pas très grand et jusqu'à ce que vous trouviez une solution au problème.

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

comme vous pouvez le voir, je calcule des choses dont vous avez besoin pour chaque ENUM puis construire pour chaque personne son MealAnalysis. Peut-être que quelqu'un trouve la solution dont vous avez besoin.

Bonne chance!

+0

Merci de passer autant de temps. Si je découvre plus, je rapporterai – Thomas

+0

Aucun problème, s'il vous plaît faire. Je suis très intéressé par ce qui nous manque ici. – BOR4