> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  drivers: shell, csharp, nodejs
-->

# $geoNear (aggregation stage)

## Definition

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

The `$geoNear` stage has the following prototype form:

```javascript
{ $geoNear: { <geoNear options> } }
```

The `$geoNear` operator accepts a [document](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-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.](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-dot-notation) This field is required for queries on timeseries collections. Starting in MongoDB 8.1, `distanceField` is optional for queries on non-timeseries collections. |
| `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.](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-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](https://www.mongodb.com/docs/manual/reference/operator/aggregation/geonear.md#std-label-pipeline-geoNear-key-param-example) 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. You must specify the `key` field for `$geoNear` on a time series collection. |
| `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. Starting in version 7.2, you can specify a valid constant [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) that resolves to a number. Specify the distance in meters if the specified point is [GeoJSON](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-GeoJSON) and in radians if the specified point is [legacy coordinate pairs.](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-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. Starting in version 7.2, you can specify a valid constant [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) that resolves to a number. Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs. |
| `near` | GeoJSON point or [legacy coordinate pair](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-legacy-coordinate-pairs) | The point for which to find the closest documents. If using a [2dsphere](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2dsphere.md#std-label-2dsphere-index) index, you can specify the point as either a GeoJSON point or legacy coordinate pair. If using a [2d](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2d.md#std-label-2d-index) 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](https://www.mongodb.com/docs/manual/tutorial/query-documents.md#std-label-read-operations-query-argument) syntax. You cannot specify a [`$near`](https://www.mongodb.com/docs/manual/reference/operator/query/near.md#mongodb-query-op.-near) predicate in the `query` field of the `$geoNear` stage. You can't use the `query` field for `$geoNear` on a [time series collection.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-landing) |
| `spherical` | boolean | Optional. Determines how MongoDB calculates the distance between two points: When `true`, MongoDB uses [`$nearSphere`](https://www.mongodb.com/docs/manual/reference/operator/query/nearsphere.md#mongodb-query-op.-nearSphere) semantics and calculates distances using spherical geometry.; When `false`, MongoDB uses [`$near`](https://www.mongodb.com/docs/manual/reference/operator/query/near.md#mongodb-query-op.-near) semantics: spherical geometry for [2dsphere](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2dsphere.md#std-label-2dsphere-index) indexes and planar geometry for [2d](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2d.md#std-label-2d-index) indexes. *Default: false.* |

## Behavior

### Distance Calculations

`$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.

### Considerations

When using `$geoNear`, consider that:

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

- [`$geoNear`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/geonear.md#mongodb-pipeline-pipe.-geoNear) requires a [geospatial index.](https://www.mongodb.com/docs/manual/geospatial-queries.md#std-label-index-feature-geospatial)

  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.

* You cannot specify a [`$near`](https://www.mongodb.com/docs/manual/reference/operator/query/near.md#mongodb-query-op.-near) predicate in the `query` field of the `$geoNear` stage.

* `$geoNear` no longer has a default limit of 100 documents.

* The `near` parameter supports the [let option](https://www.mongodb.com/docs/manual/reference/operator/aggregation/geonear.md#std-label-geoNear_let_example) and [bound let option.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/geonear.md#std-label-geoNear_bounded_let_example)

* You can use the `$geoNear` pipeline operator on any field in a [time series collection](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection). However, you cannot use the `query` field for `$geoNear` on a time series collection.

* You can create [partial](https://www.mongodb.com/docs/manual/core/index-partial.md#std-label-index-type-partial) and [2dsphere](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2dsphere.md#std-label-2dsphere-index) indexes on any field in a [time series collection.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection)

* Starting in MongoDB 8.0, [`$near`](https://www.mongodb.com/docs/manual/reference/operator/query/near.md#mongodb-query-op.-near), [`$nearSphere`](https://www.mongodb.com/docs/manual/reference/operator/query/nearsphere.md#mongodb-query-op.-nearSphere), and [`$geoNear`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/geonear.md#mongodb-pipeline-pipe.-geoNear) validate that the type of the specified [GeoJSON points](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-point) is `Point`. Any other input type returns an error.

## Examples

### MongoDB Shell

Create a collection `places` with the following documents:

```javascript
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:

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

### Maximum Distance

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`.

```javascript
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:

```javascript
{
   "_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.

### Minimum Distance

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`.

```javascript
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
     }
   }
])
```

### $geoNear with the `let` option

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.

```javascript
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`.

```javascript
{
   _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 ] } }
}
```

### $geoNear with Bound `let` Option

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

In this example, [`$lookup`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup.md#mongodb-pipeline-pipe.-lookup) uses:

- `let` to define `$pt`.

- `$geoNear` in the `pipeline`.

- `$pt` to define `near` in the `$geoNear` pipeline stage.

```javascript
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.

```javascript
{
   _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
         }
      ]
}
```

### Specify Which Geospatial Index to Use

Consider a `places` collection that has a [2dsphere](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2dsphere.md#std-label-2dsphere-index) index on the `location` field and a [2d](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2d.md#std-label-2d-index) index on the `legacy` field.

A document in the `places` collection resembles the following:

```javascript
{
   "_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`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) to return at most 5 documents.

```javascript
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:

```javascript
{
   "_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
   }
}
```

## Learn More

To learn more about related pipeline stages, see the [`$limit`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit) guide.
