本文介绍如何在EMAS Serverless的数据库中插入、创建索引和查询地理位置数据。

插入地理位置数据

EMAS Serverless支持以下几种地理位置数据类型。

地理位置数据类型 描述 示例
Point
{ type: "Point", coordinates: [ 40, 5 ] }
LineString 线
{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }
Polygon 多边形
{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}
MultiPoint 点集合
{
  type: "MultiPoint",
  coordinates: [
     [ -73.9580, 40.8003 ],
     [ -73.9498, 40.7968 ],
     [ -73.9737, 40.7648 ],
     [ -73.9814, 40.7681 ]
  ]
}
MultiLineString 线段集合
{
  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 ] ]
  ]
}
MultiPolygon 多边形集合
{
  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 ] ] ]
  ]
}
插入地理位置数据示例:
  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"
        }
  ]}

创建地理位置索引

注意 给一个字段创建了地理位置类型的索引之后,该字段只能存储地理位置数据类型的数据。

您可以通过控制台或者调用RunDBComand接口来创建地理位置类型的索引。以下为使用RunDBComand接口创建地理位置索引的Body参数示例。

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

查询地理位置数据

您可以在小程序端或者云函数中来使用地理位置查询,两者的查询语法是相同的。支持以下几种查询方法。

  • nearSphere

    按从近到远的顺序,找出字段值在给定地点附近的记录。

    说明 使用nearSphere必须给查询的字段添加地理位置索引,否则会查询失败。

    示例代码:

    mpserverless.db.collection('places').find(
      {
        location: {
          $nearSphere: {
            $geometry: {
              type: "Point",
              coordinates: [-73.9667, 40.78]
            },
            $minDistance: 1000,
            $maxDistance: 5000
          }
        }
      }
    );
    表 1. nearSphere查询方法相关参数说明
    属性 类型 必填 说明
    $geometry Point 给定的地理位置点
    $minDistance number 最小距离,单位米
    $maxDistance number 最大距离,单位米
  • geoWithin

    找出字段值在给定区域内的记录。给定区域可以是Polygon、MultiPolygon或者CenterSphere。

    说明 CenterSphere表示一个圆形,对应的值的定义是:[ [经度, 纬度], 半径 ] 。半径需以弧度计,例如需要10km的半径,则取距离除以地球半径6378.1km得出的数字。

    示例代码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]]
              ]
            }
          }
        }
      }
    );
    表 2. geometry参数说明
    属性 类型 必填 说明
    $geometry PolygonMultiPolygon 给定的区域

    示例代码2:

    mpserverless.db.collection('places').find(
      {
        location: {
          $geoWithin: {
            $centerSphere: [ [ -88, 30 ], 10/6378.1 ] }
          }
        }
      }
    );
    表 3. centerSphere参数说明
    属性 类型 必填 说明
    $centerSphere CenterSphere 给定的区域
  • geoIntersects

    找出字段值与给定的地理位置相交的记录。

    示例代码:

    mpserverless.db.collection('places').findOne(
      {
        location: {
          $geoIntersects: {
            $geometry: {
              type: "Point",
              coordinates: [-73.88, 40.78]
            }
          }
        }
      }
    );
    表 4. geoIntersects查询方法相关参数说明
    属性 类型 必填 说明
    $geometry 地理位置类型 给定的位置
  • geoNear(聚合查询)

    适用于聚合阶段,将记录按照给定点从近到远输出。

    示例代码:

    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
          }
        }
      ]
    );
    表 5. 聚合查询相关参数说明
    属性 类型 必填 说明
    near Point 给定的地理位置点
    spherical boolean 必填,值为true
    distanceField string 存放距离的输出字段名,可以用点表示法表示一个嵌套字段
    maxDistance number 最大距离,单位米
    query document 要求记录必须同时满足该条件
    distanceMultiplier number 返回时在距离上乘以该数字
    includeLocs string 列出要用于距离计算的字段,如果记录中有多个字段都是地理位置时有用
    key string 指定使用的索引字段,当集合中有多个地理位置索引时使用
注意
  1. geoNear只能出现在pipeline的第一个阶段。
  2. 必须设定distanceFielddistanceField用于指定包含计算距离的字段。
  3. 使用geoNear必须给集合添加地理位置索引,如果集合包含了多个地理位置索引,则要使用key属性来指定使用哪个字段。
  4. geoNear中的query里无法使用nearSphere(或者near)断言。