#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"]}