Ответ 1
Ответ от создателя Монгоида. Это пока невозможно. Он был добавлен как запрос функции.
По соображениям производительности я использую как можно чаще ключевое слово only()
при написании мангулярного запроса, чтобы указать поля, которые я хочу загрузить.
Обычный подозреваемый, например, когда я хочу, чтобы пользователь электронной почты всех моих администраторов был только для показа.
Я бы написал:
User.where(:groups => :admins).only(:email).each do |u|
puts u.email
end
Я делаю это, потому что моя модель пользователя заполнена множеством данных, которые я с радостью могу игнорировать при перечислении писем.
Однако теперь представьте себе, что мои пользователи ссылаются через модель Project, так что для каждого проекта я могу сделать: project.user
. Благодаря лёгкой загрузке mongoid пользователь моего объекта будет получать экземпляр (и запрашивается из БД), когда я вызываю ссылку.
Но что, если я хочу, например, перечислить все электронные письма владельца всего проекта администратора?
Я бы написал следующее:
Project.where(:admin_type => true).each do |p|
puts p.user.email
end
Основная проблема заключается в том, что при этом я загружаю весь пользовательский объект для каждого проекта, и если есть много проектов, соответствующих запросу, которое может стать довольно тяжелым. Итак, как мне загружать только электронные письма?
Я мог бы сделать это:
User.where(:_id => p.user_id).only(:email).first.email
Но это явно побеждает цель простого синтаксиса просто:
p.user.email
Мне хотелось бы написать что-то вроде: p.user.only(:email).email
, но я не могу. Любые идеи?
Алекс
Ответ от создателя Монгоида. Это пока невозможно. Он был добавлен как запрос функции.
Думаю, вам нужно денормализовать здесь. Прежде всего, прочитайте Примечание по денормализации.
Вы можете реализовать денормализацию самостоятельно, используя mongoid события или использовать большой mongoid_denormalize gem. Это довольно прямо, и после его реализации вы можете использовать p.user_email
или что-то в своих запросах.