diff --git a/lib/geocoder/model.rb b/lib/geocoder/model.rb
index d8dcbfeeb7f2f909657616ca22b444cbd75fdccc..752ee8213c3bd7d2abd30f4ed9ab99359064b15f 100644
--- a/lib/geocoder/model.rb
+++ b/lib/geocoder/model.rb
@@ -8,32 +8,6 @@ module Geocoder
   module Model
     module Base
 
-      ##
-      # Set attribute names and include the Geocoder module.
-      #
-      def geocoded_by(address_attr, options = {}, &block)
-        geocoder_init(
-          :geocode       => true,
-          :user_address  => address_attr,
-          :latitude      => options[:latitude]  || :latitude,
-          :longitude     => options[:longitude] || :longitude,
-          :geocode_block => block
-        )
-      end
-
-      ##
-      # Set attribute names and include the Geocoder module.
-      #
-      def reverse_geocoded_by(latitude_attr, longitude_attr, options = {}, &block)
-        geocoder_init(
-          :reverse_geocode => true,
-          :fetched_address => options[:address] || :address,
-          :latitude        => latitude_attr,
-          :longitude       => longitude_attr,
-          :reverse_block   => block
-        )
-      end
-
       def geocoder_options
         @geocoder_options
       end
@@ -60,6 +34,33 @@ module Geocoder
 
     module ActiveRecord
       include Base
+
+      ##
+      # Set attribute names and include the Geocoder module.
+      #
+      def geocoded_by(address_attr, options = {}, &block)
+        geocoder_init(
+          :geocode       => true,
+          :user_address  => address_attr,
+          :latitude      => options[:latitude]  || :latitude,
+          :longitude     => options[:longitude] || :longitude,
+          :geocode_block => block
+        )
+      end
+
+      ##
+      # Set attribute names and include the Geocoder module.
+      #
+      def reverse_geocoded_by(latitude_attr, longitude_attr, options = {}, &block)
+        geocoder_init(
+          :reverse_geocode => true,
+          :fetched_address => options[:address] || :address,
+          :latitude        => latitude_attr,
+          :longitude       => longitude_attr,
+          :reverse_block   => block
+        )
+      end
+
       private
       def geocoder_file_name;   "active_record"; end
       def geocoder_module_name; "ActiveRecord"; end
@@ -67,9 +68,43 @@ module Geocoder
 
     module Mongoid
       include Base
+
+      ##
+      # Set attribute names and include the Geocoder module.
+      #
+      def geocoded_by(address_attr, options = {}, &block)
+        geocoder_init(
+          :geocode       => true,
+          :user_address  => address_attr,
+          :coordinates   => options[:coordinates] || :coordinates,
+          :geocode_block => block
+        )
+      end
+
+      ##
+      # Set attribute names and include the Geocoder module.
+      #
+      def reverse_geocoded_by(coordinates_attr, options = {}, &block)
+        geocoder_init(
+          :reverse_geocode => true,
+          :fetched_address => options[:address] || :address,
+          :coordinates     => coordinates_attr,
+          :reverse_block   => block
+        )
+      end
+
+      def self.included(base); base.extend(self); end
       private
       def geocoder_file_name;   "mongoid"; end
       def geocoder_module_name; "Mongoid"; end
+
+      def geocoder_init(options)
+        super(options)
+
+        # create 2d index
+        index [[ geocoder_options[:coordinates], Mongo::GEO2D ]],
+          :min => -180, :max => 180
+      end
     end
   end
 end
diff --git a/lib/geocoder/orms/base.rb b/lib/geocoder/orms/base.rb
index 666cfbc9ed3fab217cb54d73d110e5d309ec8ebd..0c018a497f73f093d3c6c8203999710ed0394f94 100644
--- a/lib/geocoder/orms/base.rb
+++ b/lib/geocoder/orms/base.rb
@@ -72,13 +72,12 @@ module Geocoder
       def do_lookup(reverse = false)
         options = self.class.geocoder_options
         if reverse and options[:reverse_geocode]
-          args = [:latitude, :longitude]
+          args = to_coordinates
         elsif !reverse and options[:geocode]
-          args = [:user_address]
+          args = [send(options[:user_address])]
         else
           return
         end
-        args.map!{ |a| send(options[a]) }
 
         if (results = Geocoder.search(*args)).size > 0
 
diff --git a/lib/geocoder/orms/mongoid.rb b/lib/geocoder/orms/mongoid.rb
new file mode 100644
index 0000000000000000000000000000000000000000..462089635f2a9fa101d6b70c5f5ad573aa868277
--- /dev/null
+++ b/lib/geocoder/orms/mongoid.rb
@@ -0,0 +1,74 @@
+require 'geocoder/orms/base'
+
+module Geocoder::Orm
+  module Mongoid
+    include Base
+
+    def self.included(base)
+      base.class_eval do
+
+        scope :geocoded, lambda {
+          where(geocoder_options[:coordinates].ne => nil)
+        }
+
+        scope :not_geocoded, lambda {
+          where(geocoder_options[:coordinates] => nil)
+        }
+
+        scope :near, lambda{ |location, *args|
+          radius  = args.size > 0 ? args.shift : 20
+          options = args.size > 0 ? args.shift : {}
+          coords  = location.is_a?(Array) ?
+            location : Geocoder.coordinates(location)
+          conds = {:coordinates => {
+            "$nearSphere" => coords.reverse,
+            "$maxDistance" => Geocoder::Calculations.distance_to_radians(
+              radius, options[:units] || :mi)
+          }}
+          if obj = options[:exclude]
+            conds[:_id.ne] = obj.id
+          end
+          criteria.where(conds)
+        }
+      end
+    end
+
+    ##
+    # Coordinates [lat,lon] of the object.
+    # This method always returns coordinates in lat,lon order,
+    # even though internally they are stored in the opposite order.
+    #
+    def to_coordinates
+      coords = send(self.class.geocoder_options[:coordinates])
+      coords.is_a?(Array) ? coords.reverse : nil
+    end
+
+    ##
+    # Look up coordinates and assign to +latitude+ and +longitude+ attributes
+    # (or other as specified in +geocoded_by+). Returns coordinates (array).
+    #
+    def geocode
+      do_lookup(false) do |o,rs|
+        r = rs.first
+        unless r.coordinates.nil?
+          o.send :write_attribute, self.class.geocoder_options[:coordinates], r.coordinates.reverse
+        end
+        r.coordinates
+      end
+    end
+
+    ##
+    # Look up address and assign to +address+ attribute (or other as specified
+    # in +reverse_geocoded_by+). Returns address (string).
+    #
+    def reverse_geocode
+      do_lookup(true) do |o,rs|
+        r = rs.first
+        unless r.address.nil?
+          o.send :write_attribute, self.class.geocoder_options[:fetched_address], r.address
+        end
+        r.address
+      end
+    end
+  end
+end