0

I have two models, Location and Event.

class Event
  include Mongoid::Document
  field :name, type: String
  belongs_to :location
  index({'location.coordinates' => '2d'}, {unique: true})  # I added this later on because I had an error when querying on location.coordinates
end

class Location
  include Mongoid::Document
  field :coordinates, type: Array
  index({coordinates: '2d'}, {unique: true})
  has_many :events
end

Now if I create an Event with an associated location

Location.create({coordinates: [40.7127837, -74.0059413]})
Event.create({name: "foo", location: Location.first})

How can I query events near a specific location? I tried this:

Event.where('location.coordinates' => {'$near' => [40.7127837, -74.0059413], '$maxDistance' => 1000.fdiv(111.12)}).first

but it returns no results, while

Location.where('coordinates' => {'$near' => [40.7127837, -74.0059413], '$maxDistance' => 1000.fdiv(111.12)}).first

returns the Location object created earlier.

What am I doing wrong?

evuez
  • 3,257
  • 4
  • 29
  • 44
  • i haven't used ruby see here for how to make a nearSphere query with mongo https://docs.mongodb.org/manual/reference/operator/query/nearSphere/. $near and $nearSphere are differnt. The maxDistance should be in meters. what does 1000.fdiv(111.12) mean ? – astroanu Dec 09 '15 at 10:07
  • From [here](http://stackoverflow.com/a/7702456/653378), the `1000.fdiv(111.12)` should convert km to degrees (so 1000km in degrees). I edited my question, in fact the `$near` work if I query on the `Location` model directly, so I think it has more to do with mongoid... – evuez Dec 09 '15 at 10:30
  • degrees or radians ? i'm sorry, i'm not fluent with ruby syntax, but mongo does not support degree values, it must be radians. $nearSphere algorithm calculates distance as a sphere while $near would just calculate as a plain. For geolocation calculations $nearSphere will give you accurate results. – astroanu Dec 09 '15 at 11:53

1 Answers1

0

This looks like an eager loading issue to me. Have you tried the .includes(:location)

Event.includes(:location).where('location.coordinates' => {'$near' => [40.7127837, -74.0059413], '$maxDistance' => 1000.fdiv(111.12)}).first

I've worked with mongoid before, but can't seem to nail down if it is needed, and which versions it is. Eager loading is enabled by default on all models in some versions, and older versions inside the config file identity map needs to be set, but this was gone in version 4.

Andy Gauge
  • 1,428
  • 2
  • 14
  • 25