Aggregate.geoNear
1. Interface Description
Function: Output records sorted by distance from a given point, from nearest to farthest.
Declaration: geoNear(options)
Notes:
geoNearmust be the first aggregation stage A geospatial index must exist. If multiple exist, thekeyparameter must be used to specify the index to use. ThegeoNearstage does not support limiting the number of returned records via an option (for examplelimit), and does not default to 100 records. To limit the result, chain the limit stage aftergeoNear(), for example.geoNear({ ... }).limit(5).end().
2. Input Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| near | GeoJSON Point | No | The point used to calculate distance |
| spherical | boolean | Required | Required; must be true |
| maxDistance | number | Yes | Maximum distance |
| minDistance | number | Yes | Minimum distance |
| query | document | Yes | Records must satisfy this condition (same syntax as where) |
| distanceMultiplier | number | Yes | Multiplier applied to the distance when returning |
| distanceField | string | No | The output field name to store the distance, which can use dot notation to denote a nested field |
| includeLocs | string | Yes | Lists the fields to be used for distance calculation, which is useful when a record contains multiple geospatial fields |
| key | string | Yes | Specifies the geospatial index to use. If the collection has multiple geospatial indexes, the corresponding field must be specified. |
3. Response
| Parameter | Type | Required | Description |
|---|---|---|---|
| - | Aggregate | Yes | Aggregation 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
}