具有嵌入式关联的深度克隆文档 [英] Deep clone document with embedded associations

查看:53
本文介绍了具有嵌入式关联的深度克隆文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您将如何在MongoDB(蒙古包)中深度克隆文档

How would you go about deep cloning a document in MongoDB (mongoid)

我已经尝试过类似的事情

I've tried something like this;

original = Car.find(old_id)
@car = original.clone
@car._id = BSON::ObjectId.new

但是后来我反序列化了值.

But I get problems deserialization of the values afterwards.

如何使用_id以外的所有文档属性进行深层克隆?

How can I make a deep clone with all the documents attributes except the _id?

在遵循Zachary的示例之后,我对于重复文档的自定义序列化类遇到了一些问题.

After following Zachary's example I got some problems with a custom serialization class for the duplicated documents.

class OptionHash
  include Mongoid::Fields::Serializable

  # Convert the keys from Strings to Symbols
  def deserialize(object)
    object.symbolize_keys!
  end

  # Convert values into Booleans
  def serialize(object)
    object.each do |key, value|
    object[key] = Boolean::MAPPINGS[value]
  end
end

对于重复的文档,对象为nil. Car.find(old_id).attributes确实不包含带有自定义序列化的字段,为什么要这么做,以及如何包含它呢?

Object is nil for duplicated documents. Car.find(old_id).attributes indeed doesn't include the field with the custom serialization, why is that and how can I include it?

推荐答案

您无需对此调用.clone,您可以使用attributes中的原始数据.例如,下面的方法/示例将在整个文档中找到一个新ID.

You don't need to call .clone on this, you can use the raw data from attributes. For example the below method/example will give new ids throughout the entire document if it finds one.

def reset_ids(attributes)
    attributes.each do |key, value|
        if key == "_id" and value.is_a?(BSON::ObjectId)
            attributes[key] = BSON::ObjectId.new
        elsif value.is_a?(Hash) or value.is_a?(Array)
            attributes[key] = reset_ids(value)
        end        
    end
    attributes
end


original = Car.find(old_id)
car_copy = Car.new(reset_ids(original.attributes))

您现在有了Car的副本.但是这效率很低,因为它必须遍历整个散列才能使记录找出在嵌入式文档中是否有任何嵌入式文档.如果您知道结构如何,最好自行重置结构,例如,如果将部件嵌入到汽车中,则可以执行以下操作:

And you now have a copy of Car. This is inefficient though as it has to go through the entire hash for the record to figure out if there are any embedded documents in an embedded document. You would be better off resetting the structure yourself if you know how it'll be, for example, if you have a parts embedded into car, then you can just do:

original = Car.find(old_id)
car_copy = Car.new(original.attributes)
car_copy._id = BSON::ObjectId.new
car_copy.parts.each {|p| p._id = BSON::ObjectId.new}

比普通的重置要有效得多.

Which is a lot more efficient than just doing a generic reset.

这篇关于具有嵌入式关联的深度克隆文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆