引用关系的Mongoid标准

时间:2011-07-31 20:29:03

标签: mongoid mongodb

我有这两个型号:

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})

即使带有'isrc'的曲目没有字幕,它也会返回true。该怎么办?

2 个答案:

答案 0 :(得分:8)

你不能在mongo中这样做,因为Track&字幕存储在不同的文档中。 mongodb中的Exists命令只能验证自己文档中的字段,这里的关系在Tracktid文档中保存为track_id,而不是在Track文档中。所以Track没有字幕轨道。

实现此目标的一种简单方法是将您的关系从belongs_to更改为嵌入式。因此Track可以使用$ exists轻松验证字幕。

另一种方式是

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

但是这个查询的缺点是mongo多次往返以验证每个音轨的字幕数。

答案 1 :(得分:2)

对于其他任何挣扎于此的人,我发现将id映射到列表,然后使用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))是关键洞察力。