Монгоидные критерии для ссылочных отношений - PullRequest
2 голосов
/ 01 августа 2011

У меня есть 2 модели:

class Track
  include Mongoid::Document
  field :artist, type: String
  field :title, type: String
  field :isrc, type: String
  has_many :subtitles
end

class Subtitle
  include Mongoid::Document
  field :lines, type: Array
  belongs_to :track
end

Как я могу проверить, существует ли дорожка, которая имеет определенный «isrc» и имеет субтитры (независимо от того, сколько)?

Я пробовал это, но, похоже, игнорирует критерии субтитров:

Track.exists?(conditions: {isrc: my_isrc, :subtitles.exists => true})

Возвращает true, даже если дорожка с этим 'isrc' не имеет субтитров. что делать?

Ответы [ 2 ]

8 голосов
/ 01 августа 2011

Вы просто не можете сделать это в монго, так как трек и субтитры хранятся в разных документах. Команда Exists только в mongodb может проверять поля в своих собственных документах, здесь связь поддерживается в документе Subtitle как track_id, а не в документе Track. Так что у Track нет дорожки с субтитрами.

Один из простых способов добиться этого - изменить отношение с принадлежащих к встроенным. Таким образом, Track может легко проверить субтитры, используя $ существующие.

Другой способ -

Track.where(:isrc => my_isrc).select {|track| track.subtitles.count > 0}

Но недостатком в этом запросе является многократные поездки в Монго для проверки количества субтитров для каждой дорожки.

2 голосов
/ 14 февраля 2013

Для всех, кто боролся с этим, я обнаружил, что сопоставление идентификаторов со списком, а затем использование функций any_in или all_in делает свое дело.

Мне нужно было получить все сообщения, отправленные пользователю,но сообщения не связаны напрямую с моими пользователями.Вместо этого пользователи принадлежат спискам, а списки содержат много сообщений.Чтобы получить сообщения, которые «принадлежат» пользователю, я сделал это:

Вот мой контроллер:

@lists = @group.lists.where(deleted: false).order_by([:created_at, :desc])
@messages = Messages.any_in(list: @lists.map(&:id))
@messages = @messages.order_by([:created_at, :desc]).paginate(:page => params[:page], :per_page => 3)

Messages.any_in (list: @ lists.map (&: id)) был ключевым моментом.

...