Skip to content

Instantly share code, notes, and snippets.

@banker
Created July 24, 2010 23:38
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save banker/489098 to your computer and use it in GitHub Desktop.
Save banker/489098 to your computer and use it in GitHub Desktop.
# with multiple collections + commands for renaming back the collections
require 'mongo'
# Stop writing to your database.
# Then, for each collection:
# Specify the DB and COLLECTION you want to convert.
# Will insert all modified documents into a new collection
# called 'new_' + old_collection_name.
# Then you can delete the old collection and rename the new one
# once you've verified that the new collection is correct.
DB = "" # Put your db name here
COLLECTIONS = [] # Put a list of collection names here
def convert_ids(obj)
if obj.is_a?(String) && obj =~ /^[a-f0-9]{24}$/
BSON::ObjectID(obj)
elsif obj.is_a?(Array)
obj.map do |v|
convert_ids(v)
end
elsif obj.is_a?(Hash)
obj.each do |k, v|
obj[k] = convert_ids(v)
end
else
obj
end
end
def convert_collection collection
original_collection = @db[collection]
new_collection = @db['new_' + collection]
puts "db.#{collection}.renameCollection('#{original_collection.name}_original')"
puts "db.new_#{collection}.renameCollection('#{original_collection.name}')"
new_collection.drop
original_collection.find({}, :timeout => false, :sort => "_id") do |c|
c.each do |doc|
new_doc = convert_ids(doc)
new_collection.insert(new_doc, :safe => true)
end
end
end
@con = Mongo::Connection.new
@db = @con[DB]
COLLECTIONS.each do |collection|
convert_collection collection
end
@gudata
Copy link

gudata commented Sep 10, 2010

# with multiple collections + commands for renaming back the collections

require 'mongo'

# Stop writing to your database.
# Then, for each collection:
# Specify the DB and COLLECTION you want to convert.
# Will insert all modified documents into a new collection
# called 'new_' + old_collection_name.
# Then you can delete the old collection and rename the new one
# once you've verified that the new collection is correct.

DB = "re_development"

COLLECTIONS = %w(buy_statuses buys search_criterias sell_documents terms)

def convert_ids(obj)
  if obj.is_a?(String) && obj =~ /^[a-f0-9]{24}$/
    BSON::ObjectID(obj)
  elsif obj.is_a?(Array)
    obj.map do |v|
      convert_ids(v)
    end
  elsif obj.is_a?(Hash)
    obj.each do |k, v|
      obj[k] = convert_ids(v)
    end
  else
    obj
  end
end

def convert_collection collection
  original_collection = @db[collection]
  new_collection = @db['new_' + collection]
  
  puts "db.#{collection}.renameCollection('#{original_collection.name}_original')"
  puts "db.new_#{collection}.renameCollection('#{original_collection.name}')"
  new_collection.drop
  
  original_collection.find({}, :timeout => false, :sort => "_id") do |c|
    c.each do |doc|
      new_doc = convert_ids(doc)
      new_collection.insert(new_doc, :safe => true)
    end
  end
end

@con = Mongo::Connection.new
@db = @con[DB]

COLLECTIONS.each do |collection|
  convert_collection collection
end


@banker
Copy link
Author

banker commented Sep 13, 2010

Just updated the gist with your modifications.

Thanks!
Kyle

@nathanvda
Copy link

I updated the script as follows, and run it inside the rails environment, using rails runner

# After the upgrade to Mongoid, the object-ids are no longer strings, as
# described here: http://mongoid.org/docs/upgrading.html (look for UPGRADING TO 2.0.0.BETA.11 +)
#
# As a one time operation, we can convert all _id that are of type string, to BSON::ObjectId
# This script has to be run in the Rails environment, please use :
#
#     rails runner lib/tasks/convert_mongo_strings_to_objectids.rb
#


# Stop writing to your database.
# Then, for each collection:
# Specify the COLLECTIONS you want to convert.

COLLECTIONS = ["audit_logs"] # Put a list of collection names here

def convert_ids(obj)
  if obj.is_a?(String) && obj =~ /^[a-f0-9]{24}$/
    BSON::ObjectId(obj)
  elsif obj.is_a?(Array)
    obj.map do |v|
      convert_ids(v)
    end
  elsif obj.is_a?(Hash)
    obj.each do |k, v|
      obj[k] = convert_ids(v)
    end
  else
    obj
  end
end

def convert_collection collection
  original_collection = @db[collection]
  new_collection = @db['new_' + collection]
  new_collection.drop

  original_collection.find({}, :timeout => false, :sort => "_id") do |c|
    c.each do |doc|
      new_doc = convert_ids(doc)
      new_collection.insert(new_doc, :safe => true)
    end
  end

  puts "rename the collections"
  original_collection_name = original_collection.name
  original_collection.rename("#{original_collection_name}_original")
  new_collection.rename("#{original_collection_name}")

  puts "Converted #{collection}"
end

puts "Start conversion ..."
@db = Mongoid.database

COLLECTIONS.each do |collection|
  convert_collection collection
end

@banker
Copy link
Author

banker commented Jul 6, 2011

Thanks. We'll just keep your version here so that people have a few different examples.

Kyle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment