MapReduce в MongoDB - рассчитывать по категориям - PullRequest
0 голосов
/ 07 января 2020

У меня есть база данных Mon go с коллекцией, содержащей такие элементы:

collection items

Это мое назначение: task

Пример вывода:

output

Это то, что я имею до сих пор, но я действительно потерян с функцией mapreduce

db.dvdrent.mapReduce(
   `function() {
      if(this.rental_date === null)
         return;

      if(this.film.categories === undefined)
         return;

      if(this.film.categories.length !== 1)
         return;

      var hour = {
            hour: (new Date(this.rental_date)).getHours()
        };

      emit(hour, this.film.categories[0].name);

   };`,
   `function(key,values) {
      var rv = {
         categories: [],
         films: 0
      };


      values.forEach(function(x) {

         if(typeof(x) === "string")
            rv.categories.push(x);
      });

      return rv;
   };`,
   {

   }
)

1 Ответ

0 голосов
/ 08 января 2020

Вам не обязательно нужен MapReduce для выполнения такого агрегирования, если только у вас нет явного требования использовать его.

Следующее использует инфраструктуру агрегации для выполнения агрегации, которая намного быстрее, потому что она запускает скомпилированный C ++ код, в то время как код MapReduce Javascript интерпретируется.

Рассмотрим этот конвейер, который дает желаемый результат (комментарии, описывающие каждый шаг конвейера)

db.dvdrent.aggregate([
    // initial filter pipeline using $match
    { '$match': { 
        '$expr': {
            '$eq': [
                { '$size': '$film.categories' },
                1
            ]
        }
    } },

    // project a new field which holds the category name
    { '$addFields': {
        'category': { '$arrayElemAt': [ '$film.categories', 0 ] }
    } },

    // initial group - group by hour and category and aggregate counts
    { '$group': {
        '_id': {
            'hour': { 
                '$hour':  { 
                    '$dateFromString': {
                        'dateString': '$rental_date'
                    } 
                } 
            },
            'category': '$category.name'
        },
        'count': { '$sum': 1 }
    } },

    // second group - group documents from the previous group pipeline by the hour and create a lit of key/value documents
    { '$group': {
        '_id': '$_id.hour',
        'categories': {
            '$push': {
                'k': '$_id.category',
                'v': '$count'
            }
        }
    } },

    // convert the list of categories with counts documents to a key/value object/hash
    { '$project': {
        'categories': {
            '$arrayToObject': '$categories'
        }
    }}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...