mongoid geo_near with max_distance

472 views Asked by At

I am building a json API for a mobile app using rails with mongoid and am having a little bit of an issue..

We have a collection called places which stores the following:

class Place
  include Mongoid::Document
  include Mongoid::Timestamps
  has_many :posts

  field :location,          type: Array
  field :name,         type: String
  field :type_id,      type: String
  field :address,      type: String

  index({location: "2d"})
  index({ name: 1, type_id: 1, address: 1})

end

a typical JSON view of an entry would look like this:

{
    _id: ObjectId("556cf17f6cac06684b8b456a"),
    address: "406 9th Avenue, San Diego, CA, United States",
    location: [
        -117.1569243,
        32.7096999
    ],
    name: "APP HQ",
    type_id: "custom"
}

I am trying to pull places near a specific coordinate. So I use postman to run this url:

localhost:3000//v1/places/feed?lat=40.7127&lon=74 ( coordinates are for somewhere near new york -- so the place above should not be returned )

This returns:

[
    {
        "_id": "556cd5dc4a75730453010000",
        "address": "406 9th Avenue, San Diego, CA, United States",
        "created": 1433195996,
        "created_at": "2015-06-01T21:59:56.403Z",
        "geo_near_distance": 160.5248370906633,
        "location": [
            -117.1569243,
            32.7096999
        ],
        "name": "APP HQ",
        "type_id": "custom",
        "updated_at": "2015-06-01T21:59:56.403Z"
    }
]

So that's not right. So I add in the .max_distance and supply the number in meters like so:

loc = [params[:lat],params[:lng]]
        resources = Place.geo_near(loc).max_distance(params[:rad].to_i)

setting my param rad=50 returns nothing. however, changing the lat/lon in my query string to the exact in the place above returns this:

[
    {
        "_id": "556cd5dc4a75730453010000",
        "address": "406 9th Avenue, San Diego, CA, United States",
        "created": 1433195996,
        "created_at": "2015-06-01T21:59:56.403Z",
        "geo_near_distance": 32.710076318834695,
        "location": [
            -117.1569243,
            32.7096999
        ],
        "name": "APP HQ",
        "type_id": "custom",
        "updated_at": "2015-06-01T21:59:56.403Z"
    }
]

This doesn't seem right, as my geo_near_distance at that point being that my request:

localhost:3000//v1/places/[email protected]&user_token=Q6R4FNs5i3n1-zfQfbp8&lat=-117.1569243&lon=32.7096999&rad=50

is 100% identical to the location i'm looking for so it should be 0 as it's 0 meters away from the input location.

So I'm just confused here as to what the proper use case of this is to supply meters in distance to the method and have it return distance in meters in the output. Am I doing this right or am I completely out of my mind in my thinking here?

1

There are 1 answers

0
Justin On BEST ANSWER

I got this to work eventually, and here is the code that does it:

loc = [params[:lon].to_f,params[:lat].to_f]
md = (0.000621371 * params[:rad].to_i)/3959
resources = Place.geo_near(loc).max_distance(md).spherical

md takes my radius in meters and turned it into miles and then divides that by the radius of the earth to convert into radians.