MongoDb MapReduce Группировать по ключу НЕ по значению - PullRequest
0 голосов
/ 01 февраля 2012

Я пытаюсь написать функцию mapreduce для сбора статистики из mongodb. Однако .. Мой товарищ по команде, который создал структуру данных, сохранил данные следующим образом:

"statistics": {
    "20111206": {
      "CN": {
        "Beijing": {
          "cart": 1,
          "cart_users": [
            { "$oid" : "4EDD73938EAD0E5420000000" }
          ],
          "downloads": {
            "wmv": {
              "mid": 1
            }
          },
          "orders": {
            "wmv": {
              "mid": 1
            }
          }
        }
      }
    }
}

Проблема в том, что многие значения, которые мне нужно сгруппировать, просто хранятся в ключах (например, CN или BEJING в примере). Это могут быть коды стран, форматы видео и т. Д., Поэтому я не хочу кодировать ни один из них в функции mapreduce.

Функция forEach, которую я использовал для уменьшающей части, передает значения только в качестве аргумента.

Так что вопрос: есть ли способ выполнить mapReduce для этого и сгруппировать по ключам или я должен сначала преобразовать данные в новую структуру, которая выглядит примерно так:

{
  "movie_id": "4edcd4f29a4e61c00c000059",
  "country": "CN",
  "city": "Beijing",
  "list": [
    {
      "user_id": { "$oid" : "4EDD75388EAD0E5720010000" },
      "downloads": {
        "cnt": 1,
        "list": [
          {
            "format": "wmv",
            "quality": "high"
          }
        ]
      },
      "orders": {
        "cnt": 1,
        "list": [
          {
            "format": "wmv",
            "quality": "high"
          }
        ]
      }
    }
  ]
}

1 Ответ

0 голосов
/ 20 апреля 2012

Скажите, что ваша коллекция настроена на записи, подобные следующим:

> db.test_col.findOne()
{
    "_id" : ObjectId("4f90ed994d2246dd7996e042"),
    "statistics" : {
        "20111206" : {
            "CN" : {
                "Beijing" : {
                    "cart" : 1,
                    "cart_users" : [
                        {
                            "oid" : "4EDD73938EAD0E5420000000"
                        }
                    ],
                    "downloads" : {
                        "wmv" : {
                            "mid" : 1
                        }
                    },
                    "orders" : {
                        "wmv" : {
                            "mid" : 1
                        }
                    }
                }
            }
        }
    }
}

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

db.runCommand({ mapreduce: "test_col",
                map: function () {
                    var l0      = this.statistics,
                        date    = Object.keySet(l0)[0],
                        l1      = l0[date],
                        country = Object.keySet(l1)[0],
                        l2      = l1[country],
                        city    = Object.keySet(l2)[0],
                        data      = l2[city];
                    emit(country, { date: date, city: city, data: data });
                },
                reduce: function (country, values) {
                    var r = { cities: [], count: 0 };
                    values.forEach(function (v) {
                        if (r.cities.indexOf(v.city) == -1)         r.cities.push(v.city);
                        r.count++;
                    });
                    return r;
                },
                out: { reduce: "test_col_reduce" }
});

Вывод моих тестовых данных выглядит следующим образом:

> db.test_col_reduce.find()
{ "_id" : "AR", "value" : { "cities" : [ "San Juan", "Buenos Aires", "Cordoba", "Rosario" ], "count" : 18 } }
{ "_id" : "BZ", "value" : { "cities" : [ "Morico", "San Ignacio", "Corozal" ], "count" : 15 } }
{ "_id" : "CN", "value" : { "cities" : [ "Beijing", "Shanghai", "HongKong" ], "count" : 26 } }
{ "_id" : "US", "value" : { "cities" : [ "San Diego", "Los Angeles", "San Francisco", "New York" ], "count" : 27 } }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...