Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The $geoNear
aggregation stage calculates distances between a specified point and the location field in each document, sorts the documents by distance, and can optionally limit results by distance.
Syntax
The syntax for the $geoNear
operator is as follows:
{
$geoNear: {
near: {
type: "Point",
coordinates: [<longitude>, <latitude>]
},
distanceField: <field to store distance>,
maxDistance: <optional maximum distance in meters>,
minDistance: <optional minimum distance in meters>,
query: <optional query conditions>,
includeLocs: <optional boolean to include locations>,
distanceMultiplier: <optional distance multiplier>,
spherical: <boolean, must be true>,
key: <optional field path>
}
}
Parameters
Parameter | Type | Description |
---|---|---|
near |
Object | The point from which to calculate distances |
distanceField |
String | The field that contains computed distance |
maxDistance |
Number | Optional. Maximum distance in meters from point |
minDistance |
Number | Optional. Minimum distance in meters from point |
query |
Document | Optional query conditions |
includeLocs |
Boolean | Optional. Include locations in results |
distanceMultiplier |
Number | Optional. Multiply distances by this value |
spherical |
Boolean | Must be true for 2dsphere indexes |
key |
String | Optional. Field path to use for calculating distances |
Examples
Consider this sample document from the stores collection.
{
"_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f",
"name": "First Up Consultants | Bed and Bath Center - South Amir",
"location": {
"lat": 60.7954,
"lon": -142.0012
},
"staff": {
"totalStaff": {
"fullTime": 18,
"partTime": 17
}
},
"sales": {
"totalSales": 37701,
"salesByCategory": [
{
"categoryName": "Mattress Toppers",
"totalSales": 37701
}
]
},
"promotionEvents": [
{
"eventName": "Price Drop Palooza",
"promotionalDates": {
"startDate": {
"Year": 2024,
"Month": 9,
"Day": 21
},
"endDate": {
"Year": 2024,
"Month": 9,
"Day": 30
}
},
"discounts": [
{
"categoryName": "Bath Accessories",
"discountPercentage": 18
},
{
"categoryName": "Pillow Top Mattresses",
"discountPercentage": 17
}
]
}
]
}
Example 1: Basic distance calculation
Find all stores near the "VanArsdel Picture Frame Store" location, sorted by distance:
db.stores.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [-141.9922, 16.8331] // VanArsdel Picture Frame Store location
},
distanceField: "distance",
spherical: true
}
},
{
$project: {
name: 1,
distance: 1
}
}
])
This produces the following output:
{
_id: '643b2756-c22d-4063-9777-0945b9926346',
name: 'Contoso, Ltd. | Outdoor Furniture Corner - Pagacfort',
distance: 5458613.2813355485
},
{
_id: 'daa71e60-75d4-4e03-8b45-9df59af0811f',
name: 'First Up Consultants | Handbag Corner - South Salvatore',
distance: 5469362.958855379
},
{
_id: '02a78a15-b1fc-4bbd-ae1d-641b7428dc78',
name: 'VanArsdel, Ltd. | Kitchen Appliance Corner - Llewellynberg',
distance: 5472684.4628977
}..
Example 2: With distance limits and optional query
Find stores within 30 KM of "Proseware Home Entertainment Hub" that have more than 10 full-time staff:
db.stores.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [69.7296, 70.1272] // "Proseware Home Entertainment Hub" location
},
distanceField: "distance",
maxDistance: 30000, // 30 kilometers in meters
query: { "staff.totalStaff.fullTime": { $gt: 10 } },
spherical: true
}
},
{
$project: {
name: 1,
distance: 1,
"staff.totalStaff.fullTime": 1
}
}
])
This produces the following output:
{
_id: 'bbec6d3e-1666-45b4-8803-8b7ef8544845',
name: 'First Up Consultants | Baby Products Bargains - South Keenan',
staff: { totalStaff: { fullTime: 19 } },
distance: 29934.71888123174
}
Example 3: Including location data and distance multiplier
Find nearby stores with distance in kilometers and included location data:
db.stores.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [-38.4071, -47.2548] // "Fabrikam Car Accessory Outlet" location
},
distanceField: "distanceInKm",
includeLocs: "storeLocation",
distanceMultiplier: 0.001, // Convert meters to kilometers
spherical: true
}
},
{
$project: {
name: 1,
distanceInKm: 1,
storeLocation: 1
}
}
])
This produces the following output:
{
_id: 'b677846e-bb73-46ec-9cba-7d94afee382c',
name: 'Northwind Traders | Health Food Shoppe - Brooklynmouth',
storeLocation: { lat: -38.3032, lon: -132.7866 },
distanceInKm: 9.095634270192285
},
{
_id: '27c64b44-2382-4477-b3ce-c08e74882156',
name: 'Relecloud | VR Headset Gallery - West Jonasbury',
storeLocation: { lat: -37.9628, lon: -132.6637 },
distanceInKm: 34.7104536140246
},
{
_id: '505e83eb-09bc-46a4-ba85-16135611b9de',
name: 'Fabrikam, Inc. | Pharmacy Hub - Elijahville',
storeLocation: { lat: -38.0349, lon: -47.9571 },
distanceInKm: 82.92766541748313
}
Limitations
- Can't use with sharded collections
- Only one $geoNear stage per pipeline
- Must be the first stage in the pipeline
Related content
- Review options for migrating from MongoDB to Azure Cosmos DB for MongoDB (vCore).
- Read more about feature compatibility with MongoDB.