【问题标题】:With Mongoid, how to grab a collection of collections (via subdocuments)?使用 Mongoid,如何获取集合的集合(通过子文档)?
【发布时间】:2016-07-20 18:16:02
【问题描述】:

我有一个看起来像这样的 Mongoid 结构:

class Site
  has_many :web_pages
  field :name, type: String
  # ... other stuff
end      

class WebPage
  belongs_to :site
  embeds_one :content
  # ... other stuff
end

class Content
  embeds_many :images
  # ... other stuff
end

class Image
  embedded_in :content
  field :title, type: String
  field :bytes, type: Integer
  # ... other stuff
end

我想要做的是有一个给定站点名称的 Mongoid 查询,提取图像记录的集合,但只有标题和字节字段。

我知道我可以通过 Ruby 迭代地执行此操作...即,我可以获取给定站点的所有网页(按名称),遍历它们并为每个,获取它的一个内容记录,然后获取所有图像内容,仅提取标题和字节字段。但这是一个 N+1 查询,而我确信在单个查询中必须有一种方法可以提取给定站点的所有网页的所有图像(按标题)。

我欢迎任何有关如何使用 Mongoid 安排此问题的建议。

【问题讨论】:

  • MongoDB 中没有 JOIN,因此您一次只能查询一个集合;您的选择是在 Ruby 中手动执行 JOIN 或非规范化(即维护数据的多个副本,以便预先计算您的 JOIN,并且您一次只需访问一个集合),这两个选项往往有点不愉快并且容易出错。 embeds_many :imagesbelongs_to :content 对吗?我认为您不应该像这样混合嵌入和关系。
  • 我的错!图片实际上是embedded_in :content。我会改正的。
  • 您仍然会遇到多个查询,因为有多个连接。或者,您可以在 web_pages 集合中保留网站名称的副本(并使其与 sites 中的名称保持同步),这样您仍然只在一个集合中。

标签: ruby mongodb mongoid


【解决方案1】:

由于我仍然需要遍历多个集合,所以我想出的最好方法是:

def build_image_details(site)
  {}.tap do |hash|
    pages = WebPage.where(site: site)
    images = pages.collect { |page| page.content.images }.flatten
    images.each { |image| hash[image.title] = image.bytes }
  end # tap
end

该方法返回一个如下所示的哈希:

{
  "Some Image Title" => 2346435,
  "Another Image Title" => 598438
  # etc.
}

我必须查询以获取页面,然后查询每个页面以收集图像(通过内容)。但它有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 2021-06-29
    • 2022-11-16
    • 2018-04-03
    相关资源
    最近更新 更多