保存具有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'
答案 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上提出基本问题: