什么是在MongoDB中将嵌入重构为引用的最简单方法,反之亦然?

时间:2012-09-25 06:12:06

标签: mongodb refactoring

假设我有一个现有数据集,其中某些内容是嵌入式文档,但我们希望将其转换为引用。有没有任何一种自动或半自动的方式来进行这种重构。

1 个答案:

答案 0 :(得分:1)

重构本身很简单。只需将“embeds_one”替换为“has_one”(或替换映射器库的相应术语)。这是数据迁移会导致一些痛苦。或许它不会。这是我在10分钟内掀起的一个小红宝石剧本。它应该涵盖我认为你需要的东西。

source_collection = 'users'
field_to_expand = 'address'
parent_field = 'user_id'
expanded_collection = 'addresses'

require 'mongo'

db = Mongo::Connection.new.db('test')
users = db.collection(source_collection)
addresses = db.collection(expanded_collection)


# prepare test data
users.remove()
addresses.remove()

users.insert({name: 'Joe', address: {city: 'Rio de Janeiro'}})
users.find().to_a # => [{"_id"=>BSON::ObjectId('50614e910ed4c08a6a000001'), "name"=>"Joe", "address"=>{"city"=>"Rio de Janeiro"}}]


users.find().each do |u|
  # move subdocument to a separate collection
  addr = u[field_to_expand]
  addr[parent_field] = u['_id']
  addresses.insert(addr)

  # erase from original document
  users.update({_id: u['_id']}, {'$unset' => {field_to_expand => 1}})
end

users.find().to_a # => [{"_id"=>BSON::ObjectId('50614e910ed4c08a6a000001'), "name"=>"Joe"}]
addresses.find().to_a # => [{"_id"=>BSON::ObjectId('50614e910ed4c08a6a000002'), "city"=>"Rio de Janeiro", "user_id"=>BSON::ObjectId('50614e910ed4c08a6a000001')}]