Use geospatial data

Updated at:

This topic describes how to insert, index, and query geospatial data in an EMAS Serverless database.

Insert geospatial data

EMAS Serverless supports the following geospatial data types.

Geospatial data typeDescriptionExample
PointPoint
{ type: "Point", coordinates: [ 40, 5 ] }
LineStringLine
{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }
PolygonPolygon
{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}
MultiPointA collection of points
{
  type: "MultiPoint",
  coordinates: [
     [ -73.9580, 40.8003 ],
     [ -73.9498, 40.7968 ],
     [ -73.9737, 40.7648 ],
     [ -73.9814, 40.7681 ]
  ]
}
MultiLineStringA collection of line segments
{
  type: "MultiLineString",
  coordinates: [
     [ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ],
     [ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ],
     [ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ],
     [ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ]
  ]
}
MultiPolygonA collection of polygons
{
  type: "MultiPolygon",
  coordinates: [
     [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.9814, 40.7681 ], [ -73.958, 40.8003 ] ] ],
     [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.958, 40.8003 ] ] ]
  ]
}
The following example shows how to insert geospatial data:
  mpserverless.db.collection('places').insertMany([
        {
          location: { type: "Point", coordinates: [-73.88, 40.78] },
          name: "La Guardia Airport",
          category: "Airport"
        },
        {
          location: { type: "LineString", coordinates: [[113, 23], [120, 50]] },
          name: "ss Airport",
          category: "Airport"
        }
  ]}

Create a geospatial index

Important A field with a geospatial index can only store geospatial data.

You can create a geospatial index in the console or by calling the RunDBCommand API. The following example shows the Body parameter for creating a geospatial index using the RunDBCommand API.

{
    "command": "createIndex",
    "collection": "places",
    "field": {
        "location": "2dsphere"
    },
    "options": {
        "name": "location_2dsphere",
        "unique": false
    }
}

Query geospatial data

You can run geo queries in a miniapp or a cloud function. The query syntax is the same for both. The following query methods are available.

  • nearSphere

    Finds records with field values near a specified location, sorted from nearest to farthest.

    Note You must create a geospatial index for the queried field before you use nearSphere. Otherwise, the query fails.

    Example:

    mpserverless.db.collection('places').find(
      {
        location: {
          $nearSphere: {
            $geometry: {
              type: "Point",
              coordinates: [-73.9667, 40.78]
            },
            $minDistance: 1000,
            $maxDistance: 5000
          }
        }
      }
    );
    Table 1. nearSphere query parameters
    PropertyTypeRequiredDescription
    $geometryPointYesThe specified geographic point
    $minDistancenumberNoThe minimum distance in meters
    $maxDistancenumberNoThe maximum distance in meters
  • geoWithin

    Finds records with field values within a specified area. The area can be a Polygon, MultiPolygon, or CenterSphere.

    Note CenterSphere represents a circle. It is defined as [ [longitude, latitude], radius ]. The radius must be in radians. For example, to convert a 10 km radius to radians, divide 10 by the Earth's radius, which is approximately 6378.1 km.

    Example 1:

    mpserverless.db.collection('places').find(
      {
        location: {
          $geoWithin: {
            $geometry: {
              type: "Polygon",
              coordinates: [
                [[0, 0], [30, 20], [20, 30], [0, 0]],
                [[10, 10], [16, 14], [14, 16], [10, 10]]
              ]
            }
          }
        }
      }
    );
    Table 2. geometry parameter
    PropertyTypeRequiredDescription
    $geometryPolygon or MultiPolygonYesThe specified area

    Example 2:

    mpserverless.db.collection('places').find(
      {
        location: {
          $geoWithin: {
            $centerSphere: [ [ -88, 30 ], 10/6378.1 ] }
          }
        }
      }
    );
    Table 3. centerSphere parameter
    PropertyTypeRequiredDescription
    $centerSphereCenterSphereYesThe specified area
  • geoIntersects

    Finds records where the field value intersects with a specified geospatial shape.

    Example code:

    mpserverless.db.collection('places').findOne(
      {
        location: {
          $geoIntersects: {
            $geometry: {
              type: "Point",
              coordinates: [-73.88, 40.78]
            }
          }
        }
      }
    );
    Table 4. geoIntersects query parameters
    PropertyTypeRequiredDescription
    $geometryGeospatial data typeYesThe specified location
  • geoNear (aggregate query)

    This operator is used in an aggregation pipeline. It outputs records sorted from nearest to farthest from a specified point.

    Example code:

    mpserverless.db.collection('places').aggregate(
      [
        {
          $geoNear: {
            near: { type: "Point", coordinates: [113.323809, 23.097732] },
            distanceField: "distance",
            maxDistance: 2,
            query: { category: "Parks" },
            includeLocs: "location",
            spherical: true
          }
        }
      ]
    );
    Table 5. Aggregate query parameters
    PropertyTypeRequiredDescription
    nearPointYesThe specified geographic point
    sphericalbooleanYesRequired. The value must be true.
    distanceFieldstringYesThe name of the output field that stores the distance. You can use dot notation to specify a nested field.
    maxDistancenumberNoThe maximum distance in meters
    querydocumentNoRequires records to also meet this condition.
    distanceMultipliernumberNoMultiplies the distance by this number before returning it.
    includeLocsstringNoSpecifies the field to use for distance calculation. This is useful if a record has multiple geospatial fields.
    keystringNoSpecifies the index field to use. Use this when the collection has multiple geospatial indexes.
Important
  1. geoNear must be the first stage in a pipeline.
  2. Set the distanceField parameter. This parameter specifies the field that contains the calculated distance.
  3. Add a geospatial index to the collection before you use geoNear. If the collection has multiple geospatial indexes, use the key property to specify which indexed field to use.
  4. Do not use the nearSphere (or near) assertion in the query of a geoNear stage.