Запрос встроенных документов в документ с помощью MongoMapper

Каков хороший шаблон для запроса встроенных документов в документ? Например, в моем документе User есть встроенный документ предупреждений. Если я хочу узнать, есть ли у данного пользователя предупреждение с именем, я могу сделать это двумя способами, насколько я могу судить - в памяти а-ля

alert = current_user.alerts.select{|a| a.name == params[:name]}.first

или через фактический интерфейс документа a la (обратите внимание, что я не уверен на 100%, что это семантически корректно, но вы поняли):

User.where('alerts.name' => params[:name], :id => current_user.id).first

ДОЛЖЕН быть способ получше, что-то вроде

current_user.alerts.where(:name => params[:name])

возможно? А может я просто не думаю о проблеме, да?


person Brad Heller    schedule 25.05.2011    source источник
comment
Извините, я не могу ответить на ваш вопрос напрямую (недостаточно опыта работы с картографом), но посмотрите Plucky. Это язык запросов поверх MongoDB, и, возможно, он может дать вам немного более лаконичный синтаксис.   -  person Caley Woods    schedule 25.05.2011


Ответы (3)


Неа. И я думаю, что это мотивация:

В MongoMapper запросы к базе данных всегда возвращают корневой объект. Разрешение запросам возвращать встроенный документ без его родителя было бы нарушением этого и усложнило бы многие вещи (что, если я вызову .parent внутри этого встроенного документа?), Поэтому MongoMappers ошибается в сторону простоты и не претендует на то, чтобы что вещи - это то, чем они не являются. Встроенные документы хранятся в массиве внутри корневого документа в MongoDB, поэтому MongoMapper предоставляет вам массив в Ruby.

Итак, два ваших способа сделать это - предполагаемые способы сделать это.

Если вам нужен синтаксический анализатор, его не должно быть слишком сложно кодировать. Вы можете расширить Array или закодировать плагин для расширения MongoMapper прокси для встроенных документов.

person Brian Hempel    schedule 27.05.2011

Я думаю, что Mongoid поддерживает это, см. «Поиск» в руководстве по встроенным документам.

person Wolfram Arnold    schedule 25.04.2012

Вы можете сделать либо:

User.where('alerts.name' => params[:name], :id => current_user.id).fields(:alerts).first.alerts.select{|u| u.name == params[:name]}

or

User.where('alerts.name' => params[:name], :id => current_user.id).fields(:alerts).alerts.select{|u| u.name == params[:name]}.first
person Steffan Perry    schedule 22.01.2015
comment
да. Ответ не выбран, и это действительно единственный способ сделать это. Кроме того, если это внедренный документ, в соответствии с передовой практикой не должно быть очень много записей. - person Steffan Perry; 23.01.2015
comment
Я не знаю, почему вы здесь жалуетесь? В настоящее время есть только один способ сделать то, что попросил OP, и это все. Если у вас возникла проблема, почему бы не создать новый камень монго или что-то еще? И да, как я уже сказал, если у вас есть тонна таких элементов, как предупреждения, их не следует встраивать в соответствии с передовой практикой. Но ОП не спрашивал передовой опыт или мнения, просто чтобы ответить на его вопрос ... - person Steffan Perry; 23.01.2015
comment
Там я добавил новую возможность сделать это, теперь уходите, если вам нечего добавить ... - person Steffan Perry; 23.01.2015