Уменьшение карты Mongodb в 2 коллекции

#mongodb #join #mapreduce #schema-design

#mongodb #Присоединиться #mapreduce #схема-дизайн

Вопрос:

Допустим, у нас есть коллекция пользователей и сообщений. В коллекции post голосуйте за сохранение имени пользователя в качестве ключа.

 db.user.insert({name:'a', age:12});
db.user.insert({name:'b', age:12});
db.user.insert({name:'c', age:22});
db.user.insert({name:'d', age:22});

db.post.insert({Title:'Title1', vote:[a]});
db.post.insert({Title:'Title2', vote:[a,b]});
db.post.insert({Title:'Title3', vote:[a,b,c]});
db.post.insert({Title:'Title4', vote:[a,b,c,d]});
 

Мы хотели бы сгруппировать по сообщению.Заголовок и узнайте количество голосов в разных возрастах пользователей.

 > {_id:'Title1', value:{ ages:[{age:12, Count:1},{age:22, Count:0}]} }
> {_id:'Title2', value:{ ages:[{age:12, Count:2},{age:22, Count:0}]} }
> {_id:'Title3', value:{ ages:[{age:12, Count:2},{age:22, Count:1}]} }
> {_id:'Title4', value:{ ages:[{age:12, Count:2},{age:22, Count:2}]} }
 

Я просмотрел и не нашел способа получить доступ к коллекции 2 в mongodb mapreduce.
Можно ли добиться повторного уменьшения?

Я знаю, что гораздо проще встроить пользовательский документ в post, но это не лучший способ сделать, поскольку у реального пользовательского документа много свойств. Если мы включим упрощенную версию пользовательского документа, это ограничит размерность анализа.

 {Title:'Title1', vote:[{name:'a', age:12}]}
 

Комментарии:

1. Невозможно выполнить уменьшение карты для нескольких коллекций. Пожалуйста, также объясните свое обоснование, когда вы говорите «это нехороший способ сделать» в отношении встраивания документа. По возможности предоставьте свои соображения по поводу дизайна.

Ответ №1:

В MongoDB нет карты / уменьшения нескольких коллекций. MongoDB не имеет никакого синтаксиса объединения и может быть не очень хорош для специальных объединений. Вам нужно будет каким-то образом денормализовать эти данные.

У вас есть несколько вариантов:

Вариант № 1: вставьте возраст с голосованием.

 {Title:'Title1', vote:[{name:'a', age:12}]}
 

Вариант № 2: сохранить счетчик возрастов

 {Title:'Title1', vote:[a, b], age: { "12" : 1, "22" : 1 }}
 

Вариант № 3: выполните «ручное» объединение

Ваш последний вариант — написать скрипт / код, который выполняет for цикл по обеим коллекциям и правильно объединяет данные.

Таким образом, вы должны выполнить цикл post и вывести коллекцию с заголовком и списком голосов. Затем вы должны просмотреть новую коллекцию и обновить возраст, просмотрев каждую user .

Мое предложение

Выберите # 1 или # 2.

Ответ №2:

Вместо

 {name:'a', age:12}
 

Проще добавить новое поле в пользовательский документ и поддерживать его при каждом обновлении голосования.Конечно, вы можете использовать map reduce для анализа ваших данных.

 {name:'a', age:12, voteTitle:["Title1","Title2","Title3","Title4"]}