Mongoid:嵌入的文档保存在错误的父文件下

时间:2014-09-01 15:45:50

标签: ruby-on-rails mongodb mongoid

保存具有3级嵌套的文档时,子对象将保存在错误的父级下:

user = User.create
website = user.websites.create
post = website.posts.create
post2 = website.posts.create

post.images.create
post2.images.create

puts "#{user.to_json}"
puts "#{user.reload.to_json}"

每个帖子都应该有一个图像,这在脏用户对象(user.to_json)上是真的 => https://gist.github.com/vdaubry/cdc465d6d5ef84576830

但是当我重新加载用户时,所有图片都嵌入在第一篇文章下(user.reload.to_json) => https://gist.github.com/vdaubry/a9c217a467dd9ff9a7fb

这是一个错误还是我错过了一些明显的东西?

以下是用于重现此内容的类定义:

class User
  include Mongoid::Document
  embeds_many :websites
end

class Website
  include Mongoid::Document
  include Mongoid::Timestamps
  embedded_in :user
  embeds_many :posts

end

class Post
  include Mongoid::Document
  include Mongoid::Timestamps

  embedded_in :website
  embeds_many :images
end
class Image
  include Mongoid::Document
  include Mongoid::Timestamps
  embedded_in :post
end

我的宝石文件:

ruby 2.1.2p95
gem 'rails', '~> 4.1.4'
gem 'mongoid', '~> 4.0.0'

2 个答案:

答案 0 :(得分:1)

这是一个错误,我不确定错误存在于哪一端,Mongoid或MongoDB。之所以会发生这种情况,是因为Mongoid用位置运算符“$”替换了我们要推送的字段键中的索引,即“websites.0.posts.1.images”更改为“websites.0.posts。$。图像”。

引用位置运算符上的文档(斜体是我的):

  

与update()方法一起使用时,

     
      
  • 位置$运算符充当第一个元素的占位符   与查询文档匹配,
  •   

在您的情况下,图像文档会插入到创建的第一个帖子文档中,因此这可能是原因。

我不确定为什么Mongoid会这样做(替换为位置运算符)或者是$push操作所必需的。

我看到你已经为他们创建了一个问题,所以我也在那里复制我的评论。

答案 1 :(得分:0)

非常感谢您的回答!对于那些有相同问题的人来说,mongo的限制不支持多个嵌入级别的集合。

我重构了我的模型,只嵌入了2级集合。它适用于:

class User
  include Mongoid::Document
  has_many :websites
end

class Website
  belongs_to :user
  embeds_many :posts
end

class Post
  embedded_in :website
  embeds_many :images
end

class Image
  embedded_in :post
end

我认为实现这项工作的最佳方式是直接在mongo jira上提出基本问题:

https://jira.mongodb.org/browse/SERVER-831