Mongoid:将嵌入式文档转换为引用/自己的集合

时间:2012-03-16 00:17:46

标签: ruby mongodb migration mongoid

我需要将嵌入的文档转换为自己的集合,因此可以从其他集合中引用它。

假设我有Parent嵌入了许多Childs。 我在想这件事:

Parent.all.each do |p|
 p.childs.all.each do |c|
  c.raw_attributes['parent_id'] = p.id
 end
 p.save! #will save parent and cascade persist all childs onto their own coll
end

这是一个选择吗?理想情况下,我会在控制台中运行它,我只会将mongoid映射从embed_*更改为has_*,因此我不需要更改其余代码或使用其他集合作为暂存。

4 个答案:

答案 0 :(得分:10)

我认为,代码应该更像这样(没有测试)

child_coll = Mongoid.database.collection('children')

Parent.all.each do |p|
  p.childs.all.each do |c|
    c.attributes['parent_id'] = p.id

    child_coll.insert c.attributes # save children to separate collection
  end

  p.childs = nil # remove embedded data
  p.save
end

之后,您可以将embeds_many更改为has_many,并且(希望)它应该可以正常运作。

答案 1 :(得分:6)

评论太少,但我认为塞尔吉奥(否则非常有帮助)的答案可能已经过时了。使用mongoid 3.0.5我无法使用

child_coll = Mongoid.database.collection('children')

但改为使用

child_coll = Mongoid.default_session[:children]

为我做了伎俩

答案 2 :(得分:1)

对我来说,我需要删除' _id'插入之前的属性否则我将得到重复键错误。

答案 3 :(得分:1)

这是 Sergio Tulentsev 方法的更新版本,其中添加了 Pencilcheck,并更新了 sbauch 的更正。

首先,在模型中保留 embeds_many/embedded_in 语句。

其次,运行如下代码块:

child_coll =  Mongoid.client(:default).database.collection(:children)
Parent.all.each do |p|
  p.childs.all.each do |c|
    dup = c.attributes
    dup['_id'] = nil
    dup['parent_id'] = p.id
    child_coll.insert_one dup # save children to separate collection
    c.destroy
  end
  p.childs = nil # remove embedded data
  p.save
end

第三,将您的 embeds_many 更改为 has_many,将您的 embedded_in 更改为 belongs_to

结束。