Distance calculated from MongoDB geoNear command is wrong - mongodb

I have a model like the following:
var locSchema = new Schema({
loc:{
type:[Number],
index: '2dsphere'
}
});
And, I'm using $geoNear command like this:
Location.aggregate([{
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [parseInt(req.query.longitude), parseInt(req.query.latitude)]
},
"spherical": true,
"distanceField": "distance"
}
});
I'm uploading the longitude and latitude from a location and saving it in the model. And, I'm retrieving the models using the same location in geoNear command. That is same longitude and latitude.
But, in the result, I have distance as a big float where I should get 0 (or at least near 0).
{
_id: "578ca6613525d44b3f5171b8",
loc: [
79.9811093,
14.450403300000001
],
distance: 117139.297675591
}
I tried the distanceMultiplier but that does not seem to work. Where am I mistaken?

Related

MongoDB $near and $geoNear gives location with huge difference from real one

i noticed that mongoDB $near and $geoNear returns around 1km bigger distance than should be.
Point1 (current location):
lat: 54.8985,
long: 23.9036,
Point2 (location in DB):
"location" : {
"type" : "Point",
"coordinates" : [
54.91689,
23.97423
]
}
based on multiple libraries distance should be around 4.7KM
however mongodb returns: "calcDistance" : 8082 = 8km
DIFFERENCE is 4 KM!
You can check it here:
I have tried both spherical and non-spehrical and tried both $geowNear and $near
my code:
db.getCollection('collection').aggregate([
{
$geoNear: {
near: { type: 'Point', coordinates: [ 54.8985, 23.9036 ] },
distanceField: 'calcDistance',
maxDistance: 5 * 1000,
}
}
])
Any ideas why?
Look slike $near and $geoNear need lat and long swapped. That was a problem.
Refer to this: geoNear returns incorrect distance

How to store a circle and see if it overlaps with a box/ Geojson point in mongodb

I am not sure if there is a way to do this. I need to have a circle in mongodb and run a query against that with a box using $box to see if these two shapes overlap or not. However, Geojson does not support circles. What would be the best way to get this done?
The circle is stored like this:
places = {
...
"location": {
"type": "Point",
"coordinates": [
-79.390756,
43.706685
]
},
"radius": 100
}
I have two specific problems:
The first issue is that maxDistance is stored in the same object as the Geojson object and cannot be used in a $near query with $maxDistance; it only takes a number.
I do a partial postal code/ zip code search on Google Geocoding Api which returns a box with two corner coordinates like this:
"geometry": {
"bounds": {
"northeast": {
"lat": 43.710565,
"lng": -79.37363479999999
},
"southwest": {
"lat": 43.690848,
"lng": -79.40025399999999
}
}
As far as I know,I cannot use $box as it only works with $geoWithin.
Edit 1:
My initial plan with the circle and the box changed mainly because I did not find a suitable and efficient solution to this problem. Instead of checking if the circle overlaps with the box, now I check if a Geojson point is inside the circle as follows:
db.places.aggregate([
{"$geoNear": {near: { type: "Point", coordinates: [ -80.459293, 40.713640] },
distanceField: "dist.calculated", maxDistance: 100000,
key: 'myLocation', query: { 'SomeField': "..." }, spherical: true}},
{ "$match" : {$expr:{ $lte:['$dist.calculated', 'radius']}}}])
The problem here is that I d have to run a query within 100 KM first and then in another stage of the aggregation check the distance.
Is there a more efficient way to implement this? Thanks.
You can store a circle as point and radius. And you can use a $near query with a point and $maxDistance in meters which is the radius of the circle. See MongoDB Documentation.
Query to find all location, geometry field of the collection, at a certain distance from a point.
db.places.find(
{
location:
{ $near :
{
$geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
$maxDistance: 5000
}
}
}
)
Query to find if a given geometry (point, polygon(rect too)) in a query intersects with a geometry of a field in the collection.
//find quests bots that matches the users location
await Collection.find({ geometry:
{ $geoIntersects:
{
{
type: "Point",
coordinates: [
-73.99460599999999,
40.7347229
]
}
}
}
});

Find a specific field in a document, limit 5, and order by ascending distance from a gps location

I have a location collection, and have used this code that shows location near the assigned geo location below:
db.location.find({ll:{$near:[-80.12996, 25.79315]}}).limit(5).pretty()
However, now I need to expand from this and find the top 5 pizza restaurant (field is type: "Pizza"), and ordered by the geo location above (need to use near to have it by ascending). Can't figure out how to do it. I tried to use aggregate but not working for me, I might have it in the wrong order or something.
step 1: create an index of the field with have location.
db.location.createIndex( { <location field> : "2dsphere" } )
step 2: try this query replacing your coordinates in lat lng:
db.location.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [lat, lng]},
maxDistance:1000,
distanceField: "dist.calculated",
spherical: true
}
},
{
$match: {
type: "Pizza",
}
},
{
$sort: {
'dist.calculated': 1
}
},
{
$limit : 5
}
])

Difference between $center and $centerSphere in Mongo?

Currently, we are using $centerSphere to find nearby cities. One example is that for the locality Bee Cave in Texas, USA, $centerSphere correctly found the only city Austin in a radius of 30 kilometers (As per documentation, it was converted in radians). Now, for the city Lautoka in Fiji (Lat: -17.6169618, Long: 177.4504609) it is giving the error "Spherical distance would require (unimplemented) wrapping". This is question one: what does this error mean?
We tried implementing the same by using $center. I'm aware we need to give distance in miles rather than radians. After implementing, for Bee Cave, I got US cities that were thousands or hundreds of miles away. One example is Albuquerque. I'm unable to understand why these cities are coming even after following Mongo documentation properly.
I'm using the query (for Bee Cave, TX)
db.places.find{
"geo": {
$geoWithin: { $center: [ [ -97.9524, 30.3061 ] , 18.64 ] }
}
}
$centerSphere can't handle large distances, especially if it has to wrap around the poles, see this JIRA ticket.
Regarding $geoWithin it does not accept the distance in miles, but rather the circle’s radius as measured in the units used by the coordinate system, so latitude and longitude as per the documentation. That results in a very large bounding box that does include Albuquerque
You use $near instead that allows to specify a radius in meters. For example if you use this as your test data:
db.places.insert( {
name: "Bee Cave, Texas",
location: { type: "Point", coordinates: [ -97.9524, 30.3061 ] }
} );
db.places.insert( {
name: "Austin, Texas",
location: { type: "Point", coordinates: [ -97.654724, 30.210768 ] }
} );
db.places.insert( {
name: "Albuquerque",
location: { type: "Point", coordinates: [ -106.621216, 35.113281 ] }
} );
db.places.createIndex( { location: "2dsphere" } )
You can write the following query using the factor 1609.344 to convert miles to meter
db.places.find(
{
location:
{ $near:
{
$geometry: { type: "Point", coordinates: [-97.9524, 30.3061 ] },
$maxDistance: 20*1609.344
}
}
}
)
This query returns both Bee Cave,TX and Austin, TX:
{
"_id":ObjectId("5a7190124f0cd7075d349bbc"),
"name":"Bee Cave, Texas",
"location":{
"type":"Point",
"coordinates":[
-97.9524,
30.3061
]
}
}{
"_id":ObjectId("5a7190124f0cd7075d349bbd"),
"name":"Austin, Texas",
"location":{
"type":"Point",
"coordinates":[
-97.654724,
30.210768
]
}
}

MongoDB $geoNear operation "near" field usage

I have a collection "machine" with document
{
"_id" : "ac9d1db9-6a0d-47c6-97d3-a613c8dd0031",
"pin" : {
"machine":"test1",
"position" : [
-1.5716,
54.7732
]
}
}
Note: -1.5716 is lng and 54.7732 is lat
I have created a 2dsphere index on the document
db.machine.createIndex( { 'pin.position' : "2dsphere" } )
I try with 2 different versions of query (only difference in query is the near field in geoNear pipeline stage)
Query 1:
db.machine.aggregate(
[
{
"$geoNear":{
"near": [-0.2129092,51.5031594],
"limit":100,
"maxDistance":500*1000,
"distanceField": "dist.calculated",
"includeLocs": "dist.location",
"distanceMultiplier":1/1000,
"spherical": true
}
}
]
)
Note: -0.2129092 is lng and 51.5031594 is lat
Query 2
db.machine.aggregate(
[
{
"$geoNear":{
"near": { type: "Point", coordinates: [-0.2129092,51.5031594] },
"limit":100,
"maxDistance":500*1000,
"distanceField": "dist.calculated",
"includeLocs": "dist.location",
"distanceMultiplier":1/1000,
"spherical": true
}
}
]
)
Note: -0.2129092 is lng and 51.5031594 is lat
Query 1 returns me the document and provides that this document is 5.88161133560063e-05 Kms away from the search co-ordinates
Query 2 returns me the document and provides that this document is 375.135052595944 Kms away from the search co-ordinates
I cross-verify the distance between these lng/lat on a site http://andrew.hedges.name/experiments/haversine/ and see that the distance between the document and the search co-ordinates is around 374.835 Kms
It seems Query 2 is providing the correct result but am not sure as to what is the difference between Query 1 and Query 2 and if I am using it incorrectly.
Please advise
Query 1 provides the distance in legacy co-ordinate pairs and Query 2 provices the distance in meters (GeoJSON) and hence both queries are using different units
Please check the following link https://jira.mongodb.org/browse/SERVER-16652?jql=text%20~%20%22geoNear%22