地理空间

了解如何在 Redis 中使用地理空间字段并执行地理空间查询

Redis Query Engine 支持地理空间数据。此功能允许您将地理位置和几何形状存储在 JSON 对象的字段中。

注意
请注意不要将 Redis Query Engine 中的地理空间索引功能与 Redis 也支持的地理空间数据类型混淆。尽管这两种功能有一些相似之处,但该数据类型适用于更简单的用例,并且不具备 Redis Query Engine 中可用的各种格式选项和查询。

您可以索引这些字段,并使用查询按其位置或其形状与其他形状的关系查找对象。例如,如果您添加一组商店的位置,您可以找到用户位置 5 公里范围内的所有商店,或确定哪些商店位于特定城镇的边界内。

Redis 使用坐标点表示地理空间位置。您可以存储单个点,但也可以使用一组点来定义多边形形状(例如,城镇的形状)。您可以查询点和形状之间的几种类型的交互,例如点是否位于形状内或两个形状是否重叠。

Redis 可以将坐标解释为地理经纬度,也可以解释为平面上的笛卡尔坐标。地理坐标非常适合大型真实世界位置和区域(例如城镇和国家)。笛卡尔坐标更适合较小区域(例如建筑物中的房间)或游戏、模拟和其他人工场景。

存储地理空间数据

Redis 支持两种不同的地理空间数据模式类型

  • GEO:这使用一种简单格式,其中单个地理空间点被指定为数字经纬度对。

  • GEOSHAPERedis 开源版在 v7.2 及更高版本中也支持 GEOSHAPE 索引。这使用了Well-Known Text (WKT)格式的一个子集,使用地理坐标或笛卡尔坐标指定点和多边形。GEOSHAPE 字段支持比 GEO 更高级的查询,例如检查一个形状是否重叠或包含另一个形状。

下面几节将更详细地描述这些模式类型。

GEO

GEO 索引允许您将地理空间数据表示为包含经纬度对的字符串(例如,“-104.991531, 39.742043”)或这些字符串的 JSON 数组。请注意,经度值在字符串中排在前面。

例如,您可以将下面显示的 JSON 对象的 location 字段索引为 GEO

{
    "description": "Navy Blue Slippers",
    "price": 45.99,
    "city": "Denver",
    "location": "-104.991531, 39.742043"
}

{
    "description": "Bright Red Boots",
    "price": 185.75,
    "city": "Various",
    "location": [
        "-104.991531, 39.742043",
        "-105.0618814,40.5150098"
    ]
}

GEO 字段只允许基本的点和半径查询。例如,下面的查询会查找距离科罗拉多斯普林斯(经度=-104.800644,纬度=38.846127)100 英里半径范围内的产品。

FT.SEARCH productidx '@location:[-104.800644 38.846127 100 mi]'

有关可用查询选项的更多信息,请参阅地理空间查询;有关索引 GEO 字段的示例,请参阅地理空间索引

GEOSHAPE

索引为 GEOSHAPE 的字段支持来自Well-Known Text几何表示法的 POINTPOLYGON 原语。POINT 原语以类似于 GEO 字段的方式定义单个点。下面显示的示例 JSON 对象的 geom 字段指定了一个点(以笛卡尔坐标表示,使用标准的 x,y 顺序)

{
    "name": "Purple Point",
    "geom": "POINT (2 2)"
}

POLYGON 原语可以使用一系列点来近似任何形状的轮廓。按它们围绕形状出现的顺序(顺时针或逆时针)指定角点坐标,并通过使最后一个坐标与第一个坐标完全相同来确保形状“闭合”。

请注意,POLYGON 要求坐标列表周围有双层括号。这是因为您可以指定额外的形状作为逗号分隔列表,以定义封闭多边形内的“孔洞”。这些孔洞的绕线顺序必须与外部多边形相反(因此,如果外部多边形使用顺时针绕线顺序,则孔洞必须使用逆时针顺序)。下面显示的示例 JSON 对象的 geom 字段指定了一个使用顺时针绕线顺序的笛卡尔坐标正方形

{
    "name": "Green Square",
    "geom": "POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))"
}

以下示例定义了一个 POINT 原语和三个 POLYGON 原语,如下面的图像所示

POINT (2 2)
POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))
POLYGON ((2 2.5, 2 3.5, 3.5 3.5, 3.5 2.5, 2 2.5))
POLYGON ((3.5 1, 3.75 2, 4 1, 3.5 1))

您可以针对地理空间索引运行各种类型的查询。例如,下面的查询返回位于绿色正方形边界内的一个原语(来自上面的示例),但省略了正方形本身

> FT.SEARCH geomidx "(-@name:(Green Square) @geom:[WITHIN $qshape])" PARAMS 2 qshape "POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))" RETURN 1 name DIALECT 2

1) (integer) 1
2) "shape:4"
3) 1) "name"
   2) "[\"Purple Point\"]"

您可以与 GEOSHAPE 字段一起使用的四种查询操作

  • WITHIN:查找完全位于您在查询中指定的封闭形状内的点或形状。
  • CONTAINS:查找完全包含指定点或形状的形状。
  • INTERSECTS:查找其边界与另一个指定形状重叠的形状。
  • DISJOINT:查找其边界与另一个指定形状不重叠的形状。

有关这些查询类型的更多信息,请参阅地理空间查询;有关索引 GEOSHAPE 字段的示例,请参阅地理空间索引

地理坐标的局限性

地球实际上更像一个椭球体,而不是一个完美的球体。Redis Query Engine 使用的球面坐标系是地球形状的一个近似,但不完全精确。对于大多数实际使用的地理空间查询,这种近似效果很好,但如果您需要非常精确的位置数据(例如,在紧急响应系统中跟踪船只的 GPS 位置),则不应依赖它。

为此页评分
返回顶部 ↑