2012-06-28 4 views
0

У меня есть несколько монгольских моделей, на которых я запускаю mapreduce, и я хотел бы сохранить единые результаты в одной коллекции daily_stats. Моя карта & сократить функции работают отлично подходит для всех 3-х моделей, но даже при выводе через collection.mapreduce(map, reduce, {:out => "daily_stats", :raw => true}), результаты последующей карты сократить операции перезаписать предыдущие результаты, даже они не имеют перекрывающиеся ключей:Общая коллекция результатов поиска в MongoDB

{'_id': "2012-06-01", 'values': {photos: 10}} 
{'_id': "2012-06-02", 'values': {photos: 10}} 

значение для photos получить выброшены, когда последующий проход возвращается:

{'_id': "2012-06-01", 'values': {comments: 1}} 
{'_id': "2012-06-02", 'values': {comments: 6}} 

Я попытался слияния также с collection.mapreduce(map, reduce, {:out => {:merge => "daily_stats"}, :raw => true}), но это, кажется, не работает.

Любые идеи?

UPDATE

Карта & уменьшить функции, как это для каждой модели:

Карта:

function() { 
    day = Date.UTC(this.created_at.getFullYear(), this.created_at.getMonth(), this.created_at.getDate()); 
    emit(day, {users: 1}); 
    }; 

Уменьшение: функция (ключ, значение) { вар users_added_count = 0;

values.forEach(function(v) { 
     users_added_count += parseInt(v['users']) || 0; 
    }); 

    return {users: users_added_count}; 
    } 

Вот некоторая дополнительная информация о полученной схеме:

{ "_id" : 1337040000000, 
"value" : { 
    "apartments" : 280, 
    "price" : 1003653, 
    "photos" : 83, 
    "comments" : 0 } 
} 
+0

Есть ли какой-либо причине вы не сделали, и/или не может запустить карту уменьшить раз и испускают один документ, а именно: emit (day, {users: 1}, {photos: 1}, {comments: 1})? – Jenna

+0

О, я вижу. Первоначально у вас есть три отдельных коллекции: одна для пользователей, фотографий и комментариев? Я напишу пример, чтобы проиллюстрировать способ объединения данных. – Jenna

+0

Или это документ из «результирующей схемы» вашей модели входных данных? Извините, чтобы уточнить, можете ли вы предоставить больше примеров ваших данных? – Jenna

ответ

1

Если вы посмотрите документацию MongoDB для карты уменьшить (http://www.mongodb.org/display/DOCS/MapReduce# MapReduce-Outputoptions), вы увидите, что по умолчанию коллекция вывода MR заменяет все существующие коллекции тем же именем. «Merge» добавляет новые данные в старый выходной набор, но перезаписывает документы с одним и тем же ключом.

Похоже, что ваш ключ - это дата? Если

{'_id': "2012-06-01", 'values': {photos: 10}} 

и

{'_id': "2012-06-01", 'values': {comments: 1}} 

имеют один и тот же ключ, второй документ, который заменит первый при запуске MR. Вам нужно указать более уникальный ключ, или вам нужно иметь несколько выходных коллекций (возможно, один для фотографий и один для комментариев?).

+0

Правильно, ключ - это дата. Невозможно объединить элементы с одним и тем же ключом? Как вроде '$ addToSet' для полей массива? – Avishai

+0

Поскольку каждый документ должен иметь уникальное поле _id (чтобы создать уникальный индекс в документе и отслеживать местоположение документа), невозможно слить документы с тем же ключом; однако, я думаю, что есть решение вашей проблемы, связанной с функцией finalize в уменьшении карты. Если вы предоставите дополнительную информацию о своих функциях MR и схеме данных, я могу помочь. – Jenna

+0

Конечно, я добавил свою карту и уменьшил для пользователей. Другие модели почти одинаковы. – Avishai

0

Вы можете испускать с хэш-ключа, чтобы сделать его уникальным над вашими моделями

emit({day: day, type: '<model class name>'}, 1); 
Смежные вопросы