alexreisner / geocoder

Complete Ruby geocoding solution.
http://www.rubygeocoder.com
MIT License
6.35k stars 1.19k forks source link

Geocoder calculations with Mongoid #46

Closed ocxo closed 13 years ago

ocxo commented 13 years ago

I am using Mongoid 2.0 and having trouble using the distance calculations of Geocoder. I know MongoDB can do its own geospatial calculations (in 2d only) and that Geocoder overwrites those functions but I am not sure if this is where the problem is coming from.

I have my Location class defined like this: https://gist.github.com/913478

I've used your sample code to display a compass bearing based on a location in my view: https://gist.github.com/913479

I get this error:

Mongo::OperationFailure in Locations#show can't find special index: 2d for: { coordinates: { $maxDistance: 0.01263023073783309, $nearSphere: [ 0.0, 0.0 ] } }

I thought it could be an error in how the coordinates field was indexed so I ran db.locations.getIndexes() in mongo console and got this result:

{
    "name" : "_id_",
    "ns" : "neighbors_development.locations",
    "key" : {
        "_id" : 1
    },
    "v" : 0
},
{
    "ns" : "neighbors_development.locations",
    "key" : {
        "coords" : "2d"
    },
    "min" : -180,
    "max" : 180,
    "name" : "coords_2d"
},
{
    "ns" : "neighbors_development.locations",
    "unique" : false,
    "key" : {
        "coords" : 1
    },
    "name" : "coords_1",
    "v" : 0
}

Everything looks ok there to me.

I thought maybe it was a problem with my field name "coords" so I changed it to "coordinates" and then got a slightly different error:

Mongo::OperationFailure in Locations#show missing geo field (coordinates) in : { coordinates: { $maxDistance: 0.01263023073783309, $nearSphere: [ -95.9979883, 41.2523634 ] } }

Am I using the near function incorrectly? Is there a problem with the Mongoid/Geocoder integration?

alexreisner commented 13 years ago

What do you have in your Location model? You can name the field coords or coordinates but you have to tell Geocoder about it using. coordinates is the default, to override just pass an option:

geocoded_by :address, :coordinates => :coords

You'll also want to be sure your index matches the field you're using:

rake db:mongoid:create_indexes

That looks like the problem to me, but please let me know how this goes as it may not be the only issue. Thanks.

alexreisner commented 13 years ago

By the way, are you using Geocoder to fetch coordinates from Google/Yahoo/etc or are you just using it for the distance calculations? It never occurred to me that someone would use it for the distance calculations alone, and that could be part of the confusion here.

ocxo commented 13 years ago

Here is my location model https://gist.github.com/913894

I have it defined as "coordinates" in this version: geocoded_by :user_defined_location, :coordinates => :coordinates, :latitude => :lat, :longitude => :lon

(... this is probably unnecessary since the default is :coordinates but it's left over from when my field name was "coords")

I have dropped the indexes and then rake db:mongoid:create_indexes to make sure they are there. You can see the output of getIndexes() in my original post. It appears that they are created correctly.

I am fetching coords from google, storing parts of the address, and then doing distance calculations on those values retrieved from db. There may be a case where I would do a distance calc straight from google's results but for now it's using stored db values.

alexreisner commented 13 years ago

Are you using Ruby 1.8? If so, could you please try installing Geocoder from the current HEAD? Just replace the existing Geocoder line in your Gemfile with this:

gem 'geocoder', :git => "git://github.com/alexreisner/geocoder.git"

I just fixed a bug that caused the can't find special index: 2d for: { coordinates: ... } error on Ruby 1.8. If you can try it and confirm that it works I'll release a new gem version.

ocxo commented 13 years ago

Yes that works! Thank you!

alexreisner commented 13 years ago

Great. Thank you for testing. Version 0.9.13 is now available.

ocxo commented 13 years ago

I'm so new to ruby and mongodb I assumed it was something I was doing wrong. Glad to have stumbled into this one for you :)

sheharyarn commented 11 years ago

I'm getting the same error on Ruby 1.9.3 and Rails 3. I've tried running db:mongoid:create_indexes but I still get the same error. What am I doing wrong?

sheharyarn commented 11 years ago

Sorry, my bad. I was using the Mongoid 2.0.0.beta.19 - It was causing all the problems! Thanks!

RohitRox commented 11 years ago

The probem is still when used with mongoid 3 ..

Moped::Errors::QueryFailure: The operation: #<Moped::Protocol::Query
  @length=142
  @request_id=2
  @response_to=0
  @op_code=2004
  @flags=[:slave_ok]
  @full_collection_name="book_development.events"
  @skip=0
  @limit=0
  @selector={"coordinates"=>{"$nearSphere"=>[27.68, 85.31], "$maxDistance"=>0.002526046147566618}}
  @fields=nil>
failed with error 13038: "can't find special index: 2d for: { coordinates: { $nearSphere: [ 27.68, 85.31 ], $maxDistance: 0.002526046147566618 } }"

See https://github.com/mongodb/mongo/blob/master/docs/errors.md
for details about this error.
from /home/user/.rvm/gems/ruby-1.9.3-p362/gems/moped-1.4.0/lib/moped/node.rb:361:in `block in query'

did rake db:mongoid:create_indexes but it didn't work....any idea?

RohitRox commented 11 years ago

After putting this it worked index({coordinates: '2d'})