[SERVER-16652] wrong distance calcul when GeoNear used with aggregate Created: 23/Dec/14  Updated: 10/Jan/15  Resolved: 05/Jan/15

Status: Closed
Project: Core Server
Component/s: Aggregation Framework, Geo
Affects Version/s: 2.6.6
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: guipulsar Assignee: Siyuan Zhou
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to DOCS-4640 clarify unit of measurement for near ... Closed
Operating System: ALL
Steps To Reproduce:

this distance query output without aggregation is correct :
QUERY A

db.runCommand( {      
    geoNear: "tablegui",
    near: [2.298800, 48.854355], 
    maxDistance:20000000/6371 ,
    distanceMultiplier: 6371 ,   
    spherical: true,   
    query: { code_postal : { $gt : 30000 }     } ,
    limit:500}
         );

This one with aggregation is not :
QUERY B

db.tablegui.aggregate([
 
   {
     $geoNear: {
        near: { type: "Point", coordinates: [2.298800, 48.854355] },
        distanceField: "dist.calculated",
        distanceMultiplier: 6371 ,     
        maxDistance:20000000/6371 ,
        query: { code_postal:  { $gt : 30000 }   },
       limit:20000,   
       spherical: true 
     }
   }
 
    , { $project : { _id : 0  , ville : 1 , code_postal:1 , "dist.calculated":1  } } 
 
]
   
  
 )

Participants:

 Description   

wrong distance calcul when GeoNear used with aggregate .

The same Geonear query with same distanceMultiplier
and maxDistance parameters don't return the same distance calcul output when it 's querying with or without
aggregation.

When query A return 1.59861657499673,
query B return 10196136.37698665

Divion by 1000 isnot indicate in manual if i didn't miss something..



 Comments   
Comment by guipulsar [ 05/Jan/15 ]

ok thanks for ur clarifications

Comment by Siyuan Zhou [ 02/Jan/15 ]

As I mentioned before, the distance and maxDistance will be in meters if the coordinate is given in GeoJSON format, as in the following example, because GeoJSON implies the computation happens on the globe. distanceMultiplier only affects the distance in output. For instance, [0, 1] (longitude, latitude) and [0, 0] are about 111 km away, given by this website. The following example with 2.6.6 gives the correct result in kilometers.

db.tablegui.drop();
db.tablegui.insert({code_postal: 40000, loc: [0, 0]});
db.tablegui.ensureIndex({loc: "2dsphere"});
var res = db.tablegui.aggregate([
   {
     $geoNear: {
        near: { type: "Point", coordinates: [0, 1] },
        distanceField: "dist.calculated",
        distanceMultiplier: 1/1000,  // divide by 1000 to covert meters to kilometers
        maxDistance: 200 * 1000,  // 200 km
        query: { code_postal:  { $gt : 30000 }   },
        limit:2,
        spherical: true
     }
   }
]).toArray();
printjson(res);

[
	{
		"_id" : ObjectId("54a71ab0e522cdbcbb46a187"),
		"code_postal" : 40000,
		"loc" : [
			0,
			0
		],
		"dist" : {
			"calculated" : 111.31884502145034
		}
	}
]

I hope this answers your question. I am closing this ticket as "Work as Designed" as the distance is calculated correctly.

Comment by guipulsar [ 30/Dec/14 ]

At least the doc is totaly unclear...
if you want the correct result in km you have to do :

{
$geoNear: {
near:

{ type: "Point", coordinates: [2.293832, 48.8417169] }

,
distanceField: "dist.calculated",
distanceMultiplier: 1/3671,
maxDistance:2 * 3671,
query: { code_postal:

{ $gt : 30000 }

},
limit:2,
spherical: true
}

Comment by guipulsar [ 30/Dec/14 ]

so the outputt show

{ "calculated" : 10196136.37698665 }

, instead it should be

{ "calculated" : 1.019613637698665 }
Comment by guipulsar [ 30/Dec/14 ]

i know, in this example for unit in km , the calculation is wrong , this coordinates corespond to paris ,my code is corect right ?!
b.tablegui.aggregate([

{
$geoNear: {
near:

{ type: "Point", coordinates: [2.298800, 48.854355] }

,
distanceField: "dist.calculated",
distanceMultiplier: 6371 ,
maxDistance:20000000/6371 ,
query: { code_postal:

{ $gt : 30000 }

},
limit:20000,
spherical: true
}
}

, { $project :

{ _id : 0 , ville : 1 , code_postal:1 , "dist.calculated":1 }

}

]

)

the output is :
"result" : [
{
"code_postal" : 75015,
"ville" : "Paris",
"dist" :

{ "calculated" : 10196136.37698665 }

},

Comment by Siyuan Zhou [ 30/Dec/14 ]

If the distance is given as legacy coordinate paris, the unit of distance will be radian. However, distance in GeoJSON format implies the unit is meter.

In the documentation of geoNear command and $geoNear aggregation operator:

maxDistance: Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs.

Generated at Thu Feb 08 03:41:48 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.