【问题标题】:Mongoid criteria for referenced relations引用关系的 Mongoid 标准
【发布时间】:2013-02-14 16:00:52
【问题描述】:

我有这两种型号:

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。怎么办?

【问题讨论】:

    标签: mongoid mongodb


    【解决方案1】:

    您根本无法在 mongo 中这样做,因为 Track & subtitle 存储在不同的文档中。 mongodb中的exists命令只能验证自己文档中的字段,这里的关系在Subtitle文档中维护为track_id而不是在Track文档中。所以Track没有字幕的track。

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

    另一种方法是

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

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

    【讨论】:

    • 这在大型查询中效率非常低,如果说我必须检查两个文档。 /哭泣
    【解决方案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)) 是关键见解。

    【讨论】:

      猜你喜欢
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多