Mongodb карта уменьшить через 2 коллекции


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

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}]}
2 2

2 ответа:

В 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.

Вместо

{name:'a', age:12}

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

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