Skip to content

Instantly share code, notes, and snippets.

@ahoward
Forked from durran/sequence.rb
Created December 29, 2011 17:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/1535180 to your computer and use it in GitHub Desktop.
Save ahoward/1535180 to your computer and use it in GitHub Desktop.
Integer sequence ids in Mongo
require 'rubygems'
require 'mongoid'
Mongoid.configure do |config|
config.master = Mongo::Connection.new.db("test")
end
Mongoid.database.add_stored_function 'sequence', <<-__
function(sequence) {
var doc =
db.sequences.findAndModify({
'query' : {_id : sequence},
'update' : {$inc : {'value' : 1}},
'new' : true,
'upsert' : true
});
return doc.value;
}
__
module Mongoid
class Sequence
include Mongoid::Fields::Serializable
def Sequence.for(name)
sequence = new
sequence.name = name.to_s
sequence
end
attr_accessor(:name)
def instantiate(*args)
self
end
def deserialize(object)
object.to_i
end
def serialize(object)
case object
when false, nil
Mongoid.master.eval("sequence('#{ name }')").to_i
when BSON::ObjectId
object.to_s.to_i(16)
when Integer
object
else
Integer(object)
end
end
end
module Document
module ClassMethods
def sequence
@sequence ||= Sequence.for(collection.name)
end
end
end
end
class B
include Mongoid::Document
end
class A
include Mongoid::Document
A.field(:_type, :type => String, :default => name)
A.field(:_id, :type => sequence, :default => nil)
if respond_to?(:identity)
identity(:type => String, :default => proc{ generate_id }) rescue nil
end
if respond_to?(:using_object_ids)
self.using_object_ids = false
end
::Mongoid::Identity.class_eval do
def generate_id
@document.respond_to?(:generate_id) ? @document.generate_id : BSON::ObjectId.new
end
end
def self.generate_id
nil
end
def generate_id
self.class.generate_id
end
end
require 'benchmark'
B.delete_all
A.delete_all
n = 10_000
Benchmark.bm do |bm|
bm.report('B'){ n.times{ B.create } }
bm.report('A'){ n.times{ A.create } }
end
__END__
user system total real
B 2.450000 0.140000 2.590000 ( 2.595748)
A 4.320000 0.460000 4.780000 ( 8.151828)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment