Конвейер агрегации addToSet, возвращающий набор массивов записей вложенного массива вместо одного массива - PullRequest
0 голосов
/ 14 ноября 2018

Цель: Для самых быстрых запросов с C # .NET и MongoDB v4.0 выполните несколько различных операций, используя один запрос стиля конвейера агрегации для документа с записями вложенного массива, и верните выровненный набор.

Current-Problem: для записей документов первого уровня он отлично работает, неожиданные результаты при запуске различных записей вложенного массива.

Пример документа:

{  
  "title" : "Movie A",
  "released": 1984,
  "minutes" : 90,
  "category": "SciFi",
  "cost": 24000000,
  "gross": 48000000,
  "rated": "PG",
  "score": 3.4,
  "cast" : [
     {
     "name": "Buzz",
     "gender":"M",
     "age": 28,
     "country": "USA",
     "role": "Leading",
     "award" : "Golden Globe",
     "pay": 500000
     },
     {
     "name": "Sally",
     "gender":"F",
     "age": 21,
     "country": "Austrailia",
     "role": "Supporting",
     "award" : "Academy",
     "pay": 300000
     }
  ]
}

Как построить с клиентом Mongo:

использование;

db.createCollection("movies");

db.movies.insertOne({ "title" : "Movie A",  "released": 1984,  "minutes": 90,  "category": "SciFi",  "cost": 24000000,  "gross": 48000000,  "rated": "PG",  "score": 3.4,  "cast" : [ { "name": "Buzz",  "gender":"M", "age": 28, "country": "USA", "role": "Leading", "award" : "Golden Globe", "pay": 500000 }, { "name": "Sally", "gender":"F", "age": 21, "country": "Austrailia", "role": "Supporting",  "award": "Academy",  "pay": 300000  } ]});

db.movies.insertOne({ "title" : "Movie B",  "released": 1986,  "minutes": 120, "category": "Horror",  "cost": 28000000,  "gross": 40000000,  "rated": "R",  "score": 4.4,  "cast" : [ { "name": "Ryan",  "gender":"M", "age": 55, "country": "England", "role": "Leading", "award": "Oscar Nomination", "pay": 100000 }, { "name": "Sally", "gender":"F", "age": 23, "country": "Austrailia", "role": "Supporting",  "award": "Academy",  "pay": 300000  } ]});

db.movies.insertOne({ "title" : "Movie C",  "released": 1988,  "minutes": 106, "category": "Drama", "cost": 38000000,  "gross": 45000000,  "rated": "PG13",  "score": 2.4,  "cast" : [ { "name": "Pat",  "gender":"F", "age": 42, "country": "Ireland", "role": "Supporting", "award": "Irish", "pay": 350000 }, { "name": "Gene", "gender":"F", "age": 44, "country": "France", "role": "Leading",  "award": "Independent",  "pay": 280000  } ]});

C # .NET Code с Mongo v 4.0 и 2.5 версия драйвера

MongoDatabase mdb = Mongo.Controller.Instance.getDB();
var collection = mdb.GetCollection("movies");
var match = new BsonDocument
   {
     {
        "$match",
         new BsonDocument
            {
              {  "released", new BsonDocument
                  {
                     {"$gte", 1984},
                     { "$lte", 1988}
                  }
              }
           }
       }
   };

  var group = new BsonDocument
     {
         { "$group",
             new BsonDocument  {
                                 { "_id",  0},                                          
                                 { "categoryDistinct", new BsonDocument  {  { "$addToSet", "$category" }  }},
                                 { "ratedDistinct", new BsonDocument  {  { "$addToSet", "$rated" }  }},                                           
                                 { "countryDistinct", new BsonDocument  {  { "$addToSet", "$cast.country" }  }},
                                 { "awardDistinct", new BsonDocument  {  { "$addToSet", "$cast.award" }  }}                                          
                   }
            }
       };


   var pipeline = new[] { match, group };
   var args = new AggregateArgs();
   args.Pipeline = pipeline;
   args.AllowDiskUse = true;

   var results = collection.Aggregate(args).ToList();


   foreach (var obj in results)
      {
          Console.WriteLine(obj.ToString());
      }

Выход:

{ "_id" : 0, "categoryDistinct" : ["Drama", "Horror", "SciFi"], "ratedDistinct" : ["PG13", "R", "PG"], "countryDistinct" : [["Ireland", "France"], ["England", "Austrailia"], ["USA", "Austrailia"]], "awardDistinct" : [["Irish", "Independent"], ["Oscar Nomination", "Academy"], ["Golden Globe", "Academy"]] }

Примечания: categoryDistinct и RatingDistinct возвращаются, как я и ожидал, но countryDistinct и awardDistinct - нет, они возвращаются в виде записи вложенного подмассива.

Желаемый результат: countryDistinct должен был быть

["Austrailia,England,France,Ireland,USA"] 
                   awardDistinct should have been: ["Academy","Golden Globe","Independent","Irish","Oscar Nomination"];
              (I know I didn't specify a sort anywhere so if you can give a pointer that will not impact speed, that would be greatly appreciated.

Буду признателен за любые указания относительно того, как сделать это эффективно - скорость осознанно.

Заранее спасибо, Шейн

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...