committed by
Mark Paluch
parent
722b6eb389
commit
5e8d752be1
@@ -1435,6 +1435,177 @@ repo.findByLocationWithin( <4>
|
||||
<4> Use the legacy format `$polygon` operator.
|
||||
====
|
||||
|
||||
==== Metrics and Distance calculation
|
||||
|
||||
Then MongoDB `$geoNear` operator allows usage of a GeoJSON Point or legacy coordinate pairs.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
NearQuery.near(new Point(-73.99171, 40.738868))
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"$geoNear": {
|
||||
//...
|
||||
"near": [-73.99171, 40.738868]
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
NearQuery.near(new GeoJsonPoint(-73.99171, 40.738868))
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"$geoNear": {
|
||||
//...
|
||||
"near": { "type": "Point", "coordinates": [-73.99171, 40.738868] }
|
||||
}
|
||||
}
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
Though syntactically different the server is fine accepting both no matter what format the target Document within the collection
|
||||
is using.
|
||||
|
||||
WARNING: There is a huge difference in the distance calculation. Using the legacy format operates
|
||||
upon _Radians_ on an Earth like sphere, whereas the GeoJSON format uses _Meters_.
|
||||
|
||||
To avoid a serious headache make sure to set the `Metric` to the desired unit of measure which ensures the
|
||||
distance to be calculated correctly.
|
||||
|
||||
In other words:
|
||||
|
||||
====
|
||||
Assume you've got 5 Documents like the ones below:
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a5"),
|
||||
"name" : "Penn Station",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.99408, 40.75057 ] }
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a6"),
|
||||
"name" : "10gen Office",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a9"),
|
||||
"name" : "City Bakery ",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796aa"),
|
||||
"name" : "Splash Bar",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796ab"),
|
||||
"name" : "Momofuku Milk Bar",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.985839, 40.731698 ] }
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
Fetching all Documents within a 400 Meter radius from `[-73.99171, 40.738868]` would look like this using
|
||||
GeoJSON:
|
||||
|
||||
.GeoNear with GeoJSON
|
||||
====
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"$geoNear": {
|
||||
"maxDistance": 400, <1>
|
||||
"num": 10,
|
||||
"near": { type: "Point", coordinates: [-73.99171, 40.738868] },
|
||||
"spherical":true, <2>
|
||||
"key": "location",
|
||||
"distanceField": "distance"
|
||||
}
|
||||
}
|
||||
----
|
||||
Returning the following 3 Documents:
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a6"),
|
||||
"name" : "10gen Office",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
|
||||
"distance" : 0.0 <3>
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a9"),
|
||||
"name" : "City Bakery ",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
"distance" : 69.3582262492474 <3>
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796aa"),
|
||||
"name" : "Splash Bar",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
"distance" : 69.3582262492474 <3>
|
||||
}
|
||||
----
|
||||
<1> Maximum distance from center point in _Meters_.
|
||||
<2> GeoJSON always operates upon a sphere.
|
||||
<3> Distance from center point in _Meters_.
|
||||
====
|
||||
|
||||
Now, when using legacy coordinate pairs one operates upon _Radians_ as discussed before. So we use `Metrics#KILOMETERS
|
||||
when constructing the `$geoNear` command. The `Metric` makes sure the distance multiplier is set correctly.
|
||||
|
||||
.GeoNear with Legacy Coordinate Pairs
|
||||
====
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"$geoNear": {
|
||||
"maxDistance": 0.0000627142377, <1>
|
||||
"distanceMultiplier": 6378.137, <2>
|
||||
"num": 10,
|
||||
"near": [-73.99171, 40.738868],
|
||||
"spherical":true, <3>
|
||||
"key": "location",
|
||||
"distanceField": "distance"
|
||||
}
|
||||
}
|
||||
----
|
||||
Returning the 3 Documents just like the GeoJSON variant:
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a6"),
|
||||
"name" : "10gen Office",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.99171, 40.738868 ] }
|
||||
"distance" : 0.0 <4>
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796a9"),
|
||||
"name" : "City Bakery ",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
"distance" : 0.0693586286032982 <4>
|
||||
}
|
||||
{
|
||||
"_id" : ObjectId("5c10f3735d38908db52796aa"),
|
||||
"name" : "Splash Bar",
|
||||
"location" : { "type" : "Point", "coordinates" : [ -73.992491, 40.738673 ] }
|
||||
"distance" : 0.0693586286032982 <4>
|
||||
}
|
||||
----
|
||||
<1> Maximum distance from center point in _Radians_.
|
||||
<2> The distance multiplier so we get _Kilometers_ as resulting distance.
|
||||
<3> Make sure we operate on a 2d_sphere index.
|
||||
<4> Distance from center point in _Kilometers_ - take it times 1000 to match _Meters_ of the GeoJSON variant.
|
||||
====
|
||||
|
||||
[[mongo.textsearch]]
|
||||
=== Full-text Queries
|
||||
|
||||
|
||||
Reference in New Issue
Block a user