Skip to main content

Aggregate.geoNear

1. Interface Description​

Function: Output records sorted by distance from a given point, from nearest to farthest.

Declaration: geoNear(options)

Notes:

geoNear must be the first aggregation stage A geospatial index must exist. If multiple exist, the key parameter must be used to specify the index to use. The geoNear stage does not support limiting the number of returned records via an option (for example limit), and does not default to 100 records. To limit the result, chain the limit stage after geoNear(), for example .geoNear({ ... }).limit(5).end().

2. Input Parameters​

ParameterTypeRequiredDescription
nearGeoJSON PointNoThe point used to calculate distance
sphericalbooleanRequiredRequired; must be true
maxDistancenumberYesMaximum distance
minDistancenumberYesMinimum distance
querydocumentYesRecords must satisfy this condition (same syntax as where)
distanceMultipliernumberYesMultiplier applied to the distance when returning
distanceFieldstringNoThe output field name to store the distance, which can use dot notation to denote a nested field
includeLocsstringYesLists the fields to be used for distance calculation, which is useful when a record contains multiple geospatial fields
keystringYesSpecifies the geospatial index to use. If the collection has multiple geospatial indexes, the corresponding field must be specified.

3. Response​

ParameterTypeRequiredDescription
-AggregateYesAggregation object

4. Sample Code​

Suppose the collection attractions contains the following records:

{
"_id": "geoNear.0",
"city": "Guangzhou",
"docType": "geoNear",
"location": {
"type": "Point",
"coordinates": [
113.30593,
23.1361155
]
},
"name": "Canton Tower"
},
{
"_id": "geoNear.1",
"city": "Guangzhou",
"docType": "geoNear",
"location": {
"type": "Point",
"coordinates": [
113.306789,
23.1564721
]
},
"name": "Baiyun Mountain"
},
{
"_id": "geoNear.2",
"city": "Beijing",
"docType": "geoNear",
"location": {
"type": "Point",
"coordinates": [
116.3949659,
39.9163447
]
},
"name": "The Palace Museum"
},
{
"_id": "geoNear.3",
"city": "Beijing",
"docType": "geoNear",
"location": {
"type": "Point",
"coordinates": [
116.2328567,
40.242373
]
},
"name": "Great Wall"
}
const tcb = require("@cloudbase/node-sdk");
const app = tcb.init({
env: "xxx",
});

const db = app.database();
const $ = db.command.aggregate;
const _ = db.command;

exports.main = async (event, context) => {
const res = await db
.collection("attractions")
.aggregate()
.geoNear({
distanceField: "distance", // In each output record, 'distance' represents the distance from the given point
spherical: true,
near: db.Geo.Point(113.3089506, 23.0968251),
query: {
docType: "geoNear",
},
key: "location", // Not required if there is only one geospatial index field named 'location'
includeLocs: "location", // Not required if there is only one geospatial field named 'location'
})
.end();
console.log(res.data);
};

To return only the nearest 5 records, append the limit stage after geoNear:

const res = await db
.collection("attractions")
.aggregate()
.geoNear({
distanceField: "distance",
spherical: true,
near: db.Geo.Point(113.3089506, 23.0968251),
})
.limit(5)
.end();

The returned result is as follows:

{
"_id": "geoNear.0",
"location": {
"type": "Point",
"coordinates": [
113.30593,
23.1361155
]
},
"docType": "geoNear",
"name": "Canton Tower",
"city": "Guangzhou",
"distance": 4384.68131486958
},
{
"_id": "geoNear.1",
"city": "Guangzhou",
"location": {
"type": "Point",
"coordinates": [
113.306789,
23.1564721
]
},
"docType": "geoNear",
"name": "Baiyun Mountain",
"distance": 6643.521654040738
},
{
"_id": "geoNear.2",
"docType": "geoNear",
"name": "The Palace Museum",
"city": "Beijing",
"location": {
"coordinates": [
116.3949659,
39.9163447
],
"type": "Point"
},
"distance": 1894750.4414538583
},
{
"_id": "geoNear.3",
"docType": "geoNear",
"name": "Great Wall",
"city": "Beijing",
"location": {
"type": "Point",
"coordinates": [
116.2328567,
40.242373
]
},
"distance": 1928300.3308822548
}