Time for action — firing near queries in Mongoid

Let's add the gem to the Gemfile:

gem 'mongoid_spacial'

Now, for some minor changes in our code:

class Address
include Mongoid::Document

include Geocoder::Model::Mongoid
include Mongoid::Spacial::Document
field :street, type: String
...
field :coordinates, type: Array
spacial_index :coordinates

end

As we have already created indexes in the database, we don't need to run the rake db:mongoid:create_indexes command! Now, let's try our geolocation queries for the coordinates [10.123123, -87.1231231]. Let's execute the following commands:

irb> Address.geo_near([10.923124, -87.8231232], max_distance: 1)
=> []
irb > Address.geo_near([10.923124, -87.8231232], max_distance: 2)
=> #<Address _id: 4f55abf8fed0eb2f6c00002e, _type: "Address", street: "101 Union Street", zip: nil, city: "Pasedena", state: "CA", country: "US", coordinates: [10.123123, -87.1231231], location_type: "Author", location_id: BSON::ObjectId('4f55abf8fed0eb2f6c00002d')>

What just happened?

If we search within a distance equal to 1 radian around [10.92, -81.82], we don't find our address. But if we search within a distance of two radians, we find our address. So, it works! mongoid_spacial introduces a new criterion that taps the $geoNear operation in MongoDB.

Note

$geoNear is available only from MongoDB v1.8 onwards

Let's take a few steps back and see what the difference is between $near and $geoNear in MongoDB.

Differences between $near and $geoNear

The earth is round but maps are flat.

In MongoDB, when we use 2D spatial indexing and use $near, it's like searching within a box or rectangle with the center of the box as the point we want to search with. Basically, the Pythagoras theorem is used to calculate the range of the box around the 2D point.

However, the earth is not flat but is a sphere. The longitudinal distances differ depending on the latitude. The default $near query does not cater to this as it is treated as a true 2D area for searching. So, the surface area changes when we consider a point on a sphere. This is what $geoNear does. It searches in a spherical manner and hence will give more accurate results when we use geospatial indexes.

Nothing would explain this better than an example:

irb> Address.geo_near([10.923124, -87.8231232], max_distance: 1) => []
irb> Address.geo_near([10.923124, -87.8231232], max_distance: 1, spherical: true)
=> [#<Address _id: 4f55abf8fed0eb2f6c00002e, _type: "Address", street: "101 Union Street", zip: nil, city: "Pasedena", state: "CA", country: "US", coordinates: [10.123123, -87.1231231], location_type: "Author", location_id: BSON::ObjectId('4f55abf8fed0eb2f6c00002d')>]

As we can see, just by adding an option spherical, MongoDB does a spherical search and the results change.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.27.99