Docs Menu
Docs Home
/
MongoDB Manual
/ / /

$geoNear (aggregation)

On this page

  • Definition
  • Behavior
  • Examples
$geoNear

Outputs documents in order of nearest to farthest from a specified point.

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. To limit the results of $geoNear, use the $geoNear stage with the $limit stage.

The $geoNear stage has the following prototype form:

{ $geoNear: { <geoNear options> } }

The $geoNear operator accepts a document that contains the following $geoNear options. Specify all distances in the same units as those of the processed documents' coordinate system:

Field
Type
Description

distanceField

string

The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation.

distanceMultiplier

number

Optional. The factor to multiply all distances returned by the query. For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth.

includeLocs

string

Optional. This specifies the output field that identifies the location used to calculate the distance. This option is useful when a location field contains multiple locations. To specify a field within an embedded document, use dot notation.

key

Optional. Specify the geospatial indexed field to use when calculating the distance.

If your collection has multiple 2d and/or multiple 2dsphere indexes, you must use the key option to specify the indexed field path to use. Specify Which Geospatial Index to Use provides a full example.

If there is more than one 2d index or more than one 2dsphere index and you do not specify a key, MongoDB will return an error.

If you do not specify the key, and you have at most only one 2d index and/or only one 2dsphere index, MongoDB looks first for a 2d index to use. If a 2d index does not exists, then MongoDB looks for a 2dsphere index to use.

maxDistance

number

Optional. The maximum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall within the specified distance from the center point.

Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.

minDistance

number

Optional. The minimum distance from the center point that the documents can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point.

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

near

GeoJSON point or legacy coordinate pair

The point for which to find the closest documents.

If using a 2dsphere index, you can specify the point as either a GeoJSON point or legacy coordinate pair.

If using a 2d index, specify the point as a legacy coordinate pair.

query

document

Optional. Limits the results to the documents that match the query. The query syntax is the usual MongoDB read operation query syntax.

You cannot specify a $near predicate in the query field of the $geoNear stage.

spherical

boolean

Optional. Determines how MongoDB calculates the distance between two points:

  • When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry.

  • When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes.

Default: false.

$geoNear calculates distance based on the nearest point of the input document's perimeter.

For example, if the input document is a shape, $geoNear identifies the point on the shape's perimeter that is nearest to the specified point and outputs the distance between the specified point and the shape's nearest point.

When using $geoNear, consider that:

  • You can only use $geoNear as the first stage of a pipeline.

  • You must include the distanceField option. The distanceField option specifies the field that will contain the calculated distance.

  • $geoNear requires a geospatial index.

    If you have more than one geospatial index on the collection, use the keys parameter to specify which field to use in the calculation. If you have only one geospatial index, $geoNear implicitly uses the indexed field for the calculation.

Create a collection places with the following documents:

db.places.insertMany( [
{
name: "Central Park",
location: { type: "Point", coordinates: [ -73.97, 40.77 ] },
category: "Parks"
},
{
name: "Sara D. Roosevelt Park",
location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },
category: "Parks"
},
{
name: "Polo Grounds",
location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },
category: "Stadiums"
}
] )

The following operation creates a 2dsphere index on the location field:

db.places.createIndex( { location: "2dsphere" } )

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. To limit the results of $geoNear, use the $geoNear stage with the $limit stage.

The places collection above has a 2dsphere index. The following aggregation uses $geoNear to find documents with a location at most 2 meters from the center [ -73.99279 , 40.719296 ] and category equal to Parks.

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
maxDistance: 2,
query: { category: "Parks" },
includeLocs: "dist.location",
spherical: true
}
}
])

The aggregation returns the following:

{
"_id" : 8,
"name" : "Sara D. Roosevelt Park",
"category" : "Parks",
"location" : {
"type" : "Point",
"coordinates" : [ -73.9928, 40.7193 ]
},
"dist" : {
"calculated" : 0.9539931676365992,
"location" : {
"type" : "Point",
"coordinates" : [ -73.9928, 40.7193 ]
}
}
}

The matching document contains two new fields:

  • dist.calculated field that contains the calculated distance, and

  • dist.location field that contains the location used in the calculation.

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. To limit the results of $geoNear, use the $geoNear stage with the $limit stage.

The following example uses the option minDistance to specify the minimum distance from the center point that the documents can be. The following aggregation finds all documents with a location at least 2 meters from the center [ -73.99279 , 40.719296 ] and category equal to Parks.

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
minDistance: 2,
query: { category: "Parks" },
includeLocs: "dist.location",
spherical: true
}
}
])

In this example:

  • The let option is used to set an array value of [-73.99279,40.719296] to the variable $pt.

  • $pt is specified as a let option to the near parameter in the $geoNear stage.

db.places.aggregate(
[
{
"$geoNear":
{
"near":"$$pt",
"distanceField":"distance",
"maxDistance":2,
"query":{"category":"Parks"},
"includeLocs":"dist.location",
"spherical":true
}
}
],
{
"let":{ "pt": [ -73.99279, 40.719296 ] }
}
)

The aggregation returns all documents with:

  • A location at most 2 meters from the point defined in the let variable

  • A category equal to Parks.

{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
distance: 1.4957325341976439e-7,
dist: { location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] } }
},
{
_id: ObjectId("61715cf9b0c1d171bb498fd6"),
name: 'Central Park',
location: { type: 'Point', coordinates: [ -73.97, 40.77 ] },
category: 'Parks',
distance: 0.0009348548688841822,
dist: { location: { type: 'Point', coordinates: [ -73.97, 40.77 ] } }
}

The let option can bind a variable which can be used in a $geoNear query.

In this example, $lookup uses:

  • let to define $pt.

  • $geoNear in the pipeline.

  • $pt to define near in the $geoNear pipeline stage.

db.places.aggregate( [
{
$lookup: {
from: "places",
let: { pt: "$location" },
pipeline: [
{
$geoNear: {
near: "$$pt",
distanceField: "distance"
}
}
],
as: "joinedField"
}
},
{
$match: { name: "Sara D. Roosevelt Park" }
}
] );

The aggregation returns a document with:

  • The 'Sara D. Roosevelt Park' document as the main document.

  • Every document in the places collection as subDocuments using the $pt variable for calculating distance.

{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
joinedField: [
{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
distance: 0
},
{
_id: ObjectId("61715cf9b0c1d171bb498fd6"),
name: 'Central Park',
location: { type: 'Point', coordinates: [ -73.97, 40.77 ] },
category: 'Parks',
distance: 5962.448255234964
},
{
_id: ObjectId("61715cfab0c1d171bb498fd8"),
name: 'Polo Grounds',
location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] },
category: 'Stadiums',
distance: 13206.535424939102
}
]
}

Consider a places collection that has a 2dsphere index on the location field and a 2d index on the legacy field.

A document in the places collection resembles the following:

{
"_id" : 3,
"name" : "Polo Grounds",
"location": {
"type" : "Point",
"coordinates" : [ -73.9375, 40.8303 ]
},
"legacy" : [ -73.9375, 40.8303 ],
"category" : "Stadiums"
}

The following example uses the key option to specify that the aggregation should use the location field values for the $geoNear operation rather than the legacy field values. The pipeline also uses $limit to return at most 5 documents.

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. To limit the results of $geoNear, use the $geoNear stage with the $limit stage.

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] },
key: "location",
distanceField: "dist.calculated",
query: { "category": "Parks" }
}
},
{ $limit: 5 }
])

The aggregation returns the following:

{
"_id" : 8,
"name" : "Sara D. Roosevelt Park",
"location" : {
"type" : "Point",
"coordinates" : [
-73.9928,
40.7193
]
},
"category" : "Parks",
"dist" : {
"calculated" : 974.175764916902
}
}
{
"_id" : 1,
"name" : "Central Park",
"location" : {
"type" : "Point",
"coordinates" : [
-73.97,
40.77
]
},
"legacy" : [
-73.97,
40.77
],
"category" : "Parks",
"dist" : {
"calculated" : 5887.92792958097
}
}

Back

$fill