Агрегации с картой / уменьшить mongodb - PullRequest
0 голосов
/ 17 декабря 2011

У меня есть данные, которые организованы иерархически, и я хотел бы вычислить агрегации на нескольких уровнях в рамках одной операции mongodb map / Reduce.Есть ли способ сделать это?

Пример:

{ street: "A", district: "1", city: "Z", nb_users: 1 }
{ street: "A", district: "1", city: "Z", nb_users: 2 }
{ street: "B", district: "1", city: "Z", nb_users: 3 }
{ street: "B", district: "1", city: "Z", nb_users: 2 }
{ street: "C", district: "1", city: "Z", nb_users: 4 }
{ street: "C", district: "1", city: "Z", nb_users: 3 }
{ street: "A", district: "2", city: "Z", nb_users: 5 }
{ street: "B", district: "2", city: "Z", nb_users: 6 }
{ street: "B", district: "2", city: "Z", nb_users: 3 }

Результат:

{ street: "A", district: "1", city: "Z", nb_users_street: 3, nb_users_district: 15, nb_users_city: 29 }
{ street: "B", district: "1", city: "Z", nb_users_street: 5, nb_users_district: 15, nb_users_city: 29 }
{ street: "C", district: "1", city: "Z", nb_users_street: 7, nb_users_district: 15, nb_users_city: 29 }
{ street: "A", district: "2", city: "Z", nb_users_street: 5, nb_users_district: 14, nb_users_city: 29 }
{ street: "B", district: "2", city: "Z", nb_users_street: 9, nb_users_district: 14, nb_users_city: 29 }

Спасибо за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 18 декабря 2011

MongoDB 2.2 представит новую структуру агрегирования, которая будет намного быстрее и, возможно, сможет лучше справиться с этой ситуацией. Тем не менее, я согласен с Расселом, что использование 3 м / р будет намного проще в долгосрочной перспективе. Если вы хотите настроить свой окончательный документ на что-то другое, как показано ниже, вы сможете сделать это за один раз, но код становится довольно сложным. Тем не менее, его преимущество заключается в том, что он более похож на документ.

result: {
  city: "Z",
  nb_users: 29
  districts: {
    "1": {
      nb_users: 15,
      streets: {
        "A": 3,
        "B": 5,
        "C": 7
      }    
    },
    "2" : {
      nb_users: 14,
      streets: {
        "A": 5,
        "B": 9
      }   
    }
  }
}
0 голосов
/ 17 декабря 2011

Нет, простого способа сделать это не существует.

Поскольку вы хотите агрегировать по street, district и city, вам нужно будет использовать их все как часть ключа ваших излучаемых объектов, так что ваш map функция, скорее всего, будет выглядеть примерно так:

function(){
  emit ( 
    { street : this.street, district : this.district, city : this.city }, 
    {nb_users : this.nb_users } 
  );
} 

Поскольку функция уменьшения объединяет записи только с соответствующими ключами, вы сможете комбинировать записи только в том случае, если улица, район и город одинаковы - это означает, что вы не сможете рассчитать общая сумма для района или города из этих излучаемых объектов, поскольку они охватывают несколько улиц.

Выполнение трех отдельных карт / сокращений в три отдельных выходных набора сделает код проще и проще для понимания, а также устранит избыточность повторений nb_users_district и nb_users_city для каждой строки уровня улицы.

На самом деле, три отдельные функции map / Reduction будут настолько просты, что вы сможете использовать встроенную в MongoDB функцию group, которая, как я считаю, дает некоторые преимущества в производительности по сравнению со стандартной картой / Reduce.

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