Fouad
Fouad

Reputation: 855

Mongoose geo query does not return correct result

I am trying to query a database where i am storing coordinates for location near certain coordinates and also specifying a maxDistance. I read on the official mongo documentation that the maxDistance in in meters. the collection schema is as follows:

var BranchSchema = new Schema({
parentId: {
    type: Schema.Types.ObjectId,
    required: 'The ID of the parent is required.',
    index: true
},
name: {
    type: 'String',
    required: 'The branch name is required.'
},
location: {
    type: [Number],
    index: {
        type: '2dsphere'
    }
}
});

i had inserted a document that has the following information:

{
"parentId" : ObjectId("54ee08c2d903aca72291f120"),
"name" : "Branch1",
"_id" : ObjectId("54ee422809f242122744990c"),
"location" : [ 
    33.377796, 
    35.480911
]
}

i then try to query for lat=33.901948 and long=35.576797 with a max distance 5. i used an online tool on the web (http://www.movable-type.co.uk/scripts/latlong.html) that gives the distance between lat=33.901948 and long=35.576797 and lat=33.377796 and long=35.480911 as 58KM, obviously greater than 5 meters and still the query return the result while it shouldn't

the mongoose query is as follows:

 Branch.where('location').near({
    center: [lat, long],
    maxDistance: proximity,
    spherical: true
}).exec(function (err, branches) {
    if (err) {
        return res.status(400)
            .send({
                message: errors.getErrorMessage(err)
            });
    }
    return res.json(branches);
});

Thanks in advance

Upvotes: 1

Views: 601

Answers (1)

efkan
efkan

Reputation: 13227

Actually, I've been seeing some mistakes on your issue;

1- Index.

 - 2dsphere index if specifying a GeoJSON point
 - 2d index if specifying a point using legacy coordinates.

Your schema uses a legacy coordinate field. It's not a GeoJSON field. Because a GeoJSON has to be included a coordinate type value like the following;

location: {
            'type': { type: String, default: 'Point' },
             coordinates: [Number]
           } 

If you want to legacy coordinate field you should use 2d index.

2- the order of lat. and lng. Your codes must start with Longitude

IMPORTANT
Specify coordinates in this order: “longitude, latitude.”

On the other hand if you wanna use legacy 2d index you might use the following codes;

{ location : { $near : [ -73.9667, 40.78 ], $maxDistance: 0.10 } }

The above codes hava a $maxDistance parameter that specifies the radius. I think you should check this out. Beacuse you must consider the following line to find 5 meters proximity.

5 meters = (5 / 6371000) radius of the earth

So, I think the following codes work;

Branch.where('location').near({
    center: [long, lat],
    maxDistance: 5/6371000,
    spherical: true
}).exec(function (err, branches) {
    if (err) {
        return res.status(400)
            .send({
                message: errors.getErrorMessage(err)
            });
    }
    return res.json(branches);
});

Or

Branch.find(
    { location : { $near : [ -73.9667, 40.78 ], $maxDistance: 5/6371000 }}, 
    function (err, branches) {
        if (err) {
            return res.status(400)
            .send({
                message: errors.getErrorMessage(err)
            })
        }
        return res.json(branches);
    }
)  

I hope this helps, good luck!

Upvotes: 2

Related Questions