2013-02-13 7 views
0

Я использую Mongoid и MongoDB в приложении, которое я делаю. У меня есть пользователь, который имеет один профиль, как так:Mongoid Map Уменьшить с has_one

class User 

field :email, :type => String 
field :name, :type => String 
field :date_of_birth, :type => DateTime 
has_one :profile 

end 

class Profile 

field :votes, :type => Hash 
field :biography, :type => String 
belongs_to :profile 

end 

голосов хэш структурирована следующим образом:

profile : { 
    "user_id" : ObjectId("511b76b0e80c505750000031"), 
    "votes": { 
    "vote_count": 3, 
    "up_votes": 3, 
    "down_votes": 0 
    } 
} 

Я бегу карты уменьшить примерно так:

map = " 
    function() { 
    values = { 
     name: this.name 
    } 
    emit(this._id, values); 
    } 
" 

reduce = " 
    function (key, emits) { 
    return emits; 
    } 
" 

User.map_reduce(map, reduce).out(replace: "leaderboards").each do |document| 
    ap document 
end 

это работает прекрасно и создает новую коллекцию в Mongo, называемую лидерами. Однако я пытаюсь сопоставить некоторые данные из профиля, поэтому он включает поле vote_count из профиля.

сути делает моя функция карты выглядеть так:

map = " 
    function() { 
    values = { 
     name: this.name, 
     votes: this.profile.votes.vote_count 
    } 
    emit(this._id, values); 
    } 
" 

Однако я с трудом хватая профиль, связанный с пользователем. Кто-нибудь знает, как я могу извлечь данные из профиля пользователей?

Если что-то неясно, дайте мне знать. Любая помощь будет оценена по достоинству.

Тони

ответ

1

нет никакого способа, в MongoDB делать «присоединяется» данные из различных коллекций на стороне сервера - вы должны сделать их в клиентском приложении, или, лучше, считают document embedding, тем более, что это соотношение 1: 1 между вашим пользователем и коллекциями профилей.

Теперь, если изменение конструкции не вариант, вы можете выполнить два MapReduce() в следующей последовательности:

  1. один у вас есть на пользователе, но с использованием в качестве ключа user_id, и добавьте имя как поле
  2. MapReduce на профиле с тем же user_id ключом и vote_count, указывающим merge output в турнирных коллекции

ли эта помощь?

С уважением

Ronald

Смежные вопросы