本文首发于 Nebula Graph Community 公众号

本文主要介绍了地理空间数据(Geospatial Data)以及它在 Nebula Graph 中的具体实践。

Geospatial Data 在 Nebula Graph 中的实践

什么是 Geospatial Data

地理空间数据(Geospatial Data)是包含简单地理空间要素信息的数据,比如点(point)、线(linestring)、多边形(polygon),或是其他更复杂的形状。

Nebula Graph 在 2.6 版本中引入了对 Geospatial Data 完整的支持,包括地理空间数据的存储、计算,以及索引。Nebula Graph 目前支持 Geography 类型的地理空间数据,Geography 类型是建模在地球空间坐标系上由经纬度坐标对表示的地理位置信息。

Geospatial Data -- 地理空间数据使用

创建 Schema

这里仅以 Tag 为例,当然 Edgetype 上同样可以将 Geography 类型作为属性列。

Nebula 目前支持点、线、多边形三种空间数据类型。下面介绍一下如何如何创建 Geography 类型属性以及如何插入地理空间数据到 Nebula 中。

CREATE TAG any_shape(geo geography);
CREATE TAG only_point(geo geography(point));
CREATE TAG only_linestring(geo geography(linestring));
CREATE TAG only_polygon(geo geography(polygon));

geography 属性后面没有指定具体的地理形状信息时,代表该列可以存储任意地理形状的数据;当指定形状类型时,则代表只能存储该形状的地理数据,比如 geography(point),就代表该列只能存储 point 形状的地理位置信息。

插入数据

向 Tag any_shapegeo 列插入数据:

INSERT VERTEX any_shape(geo) VALUES "101":(ST_GeogFromText("POINT(120.12 30.16)"));
INSERT VERTEX any_shape(geo) VALUES "102":(ST_GeogFromText("LINESTRING(3 8, 4.7 73.23)"));
INSERT VERTEX any_shape(geo) VALUES "103":(ST_GeogFromText("POLYGON((75.3 45.4, 112.5 53.6, 122.7 25.5, 93.9 28.6, 75.3 45.4))"));

向 Tag only_pointgeo 列插入数据:

INSERT VERTEX only_point(geo) VALUES "201":(ST_Point(120.12,30.16)"));;

向 Tag only_linestringgeo 插入数据:

INSERT VERTEX only_linestring(geo) VALUES "302":(ST_GeogFromText("LINESTRING(3 8, 4.7 73.23)"));

向 Tag only_polygongeo 列插入数据:

INSERT VERTEX only_polygon(geo) VALUES "403":(ST_GeogFromText("POLYGON((75.3 45.4, 112.5 53.6, 122.7 25.5, 93.9 28.6, 75.3 45.4))"));

当插入地理数据形状不符合该列地理形状要求时,会报错无法插入:

(root@nebula) [geo]> INSERT VERTEX only_polygon(geo) VALUES "404":(ST_GeogFromText("POINT((75.3 45.4))"));
[ERROR (-1005)]: Wrong value type: ST_GeogFromText("POINT((75.3 45.4))")

我们可以看到地理空间数据插入方法比较奇特,和 int、string、bool 等基本类型的插入很不一样。

我们以 ST_GeogFromText("POINT(120.12 30.16)") 为例,ST_GeogFromText 是一个地理位置信息解析函数,它接受一个 string 类型的 WKT(Well-Known Text)标准格式表示的地理位置数据:

POINT(120.12 30.16) 代表一个东经 120°12′,北纬 30°16′ 的地理位置点。ST_GeogFromText 函数会从 wkt 参数中解析并构造一个 geography 数据对象,然后 INSERT 语句会将其以 WKB(Well-Known Binary)标准存储在 Nebula 中。

Geospatial functions -- 地理空间函数

Nebula 支持的地理空间函数可以分为以下几大类:

  • 构造函数

    • ST_Point(longitude, latitude),根据一对经纬度构造一个 geography point 对象
  • 解析函数
    • ST_GeogFromText(wkt_string),从 wkt 文本中解析 geography 对象
    • ST_GeogFromWKB(wkb_string),从 wkb 文本中解析 geography 对象 # 尚未正式支持,因为 Nebula还未支持二进制字符串
  • 格式设置函数
    • ST_AsText(geogrpahy),将 geogrpahy 对象以 wkt 文本格式输出
    • ST_AsBinary(geography),将 geography 对象以 wkb 文本格式输出 # 尚未正式支持,因为 Nebula 还未支持二进制字符串
  • 转换函数
    • ST_Centroid(geography),计算 geography 对象的重心,重心是一个 geography point 对象
  • 谓词函数
    • ST_Intersects(geography_1, geography_2),判断两个 geography 对象是否相交
    • ST_Covers(geography_1, geography_2),判断第一个 geography 对象是否完全覆盖第二个
    • ST_CoveredBy(geography_1, geography_2),ST_Covers 的反义词
    • ST_DWithin(geography_1, geography_2, distance_in_meters),判断两个 geography 对象的最短距离是否小于给定距离
  • 度量函数
    • ST_Distance(geography_1, geography_2),计算两个 geography 对象之间的距离

这些函数接口遵循 OpenGIS Simple Feature Access 以及 ISO SQL/MM 标准,具体用法参见Nebula 文档

Geospatial index -- 地理空间索引

什么是地理空间索引?

地理空间索引用于基于空间谓词函数的的地理形状的快速过滤,如:ST_Intersects、ST_Covers 等。

Nebula 使用Google S2库做空间索引。

S2 库将地球表面投影到一个外切的正方体上,然后对正方体的每一个正方形表面递归地进行 n 次四等,最后使用一条空间填充曲线--希尔伯特曲线去连接这些小正方格子的中心。

当 n 无穷大时,这条希尔伯特曲线就几乎填满了正方形。

S2 库使用的是 30 阶的希尔伯特曲线。

如下图, 是用希尔伯特曲线填充地地球表面的示意图:

可以看到,地球表面最终被这些希尔伯特曲线划分成了一个个单元格。对于地球表面的任意地理形状,比如一个城市、一条河流、一个人的位置我们都可以用若干个这样的格子去完全覆盖住这个地理形状。

每个格子都有一个唯一的 int64 的 CellID 来标识。因此,地理对象的空间索引就是构建完全覆盖该地理形状的 S2 格子的集合。

当构建地理空间对象的索引时,会构造一个完全覆盖被索引对象的不同 S2 单元格的集合。基于空间谓词函数的索引查询通过查找覆盖所查询对象的 S2 单元格的集合与覆盖被索引对象的 S2 单元格之间的交集,来快速过滤掉大量不相关的地理对象。

创建 geography 索引

CREATE TAG any_shape_geo_index on any_shape(geo)

对于形状为 point 的地理数据,可以用一个 level 为 30 的 S2 单元格来表示它,因此一个 point 对应一个索引条目;对于形状为 linestring 和 polygon 的地理数据,我们使用多个不同 level 的 S2 单元格来覆盖,因此会对应多个索引条目;

空间索引会用来加速所有 geo 谓词的查找速度,比如对于如下语句

LOOKUP ON any_shape WHERE ST_Intersects(any_shape.geo, ST_GeogFromText("LINESTRING(3 8, 4.7 73.23)"));

当 any_shape 的 geo 列上没有空间索引时,该语句会先将 any_shape 的所有数据读到内存,然后用来计算是否和点(3.0, 8.0)相交,这个计算的开销一般是比较昂贵的。当 any_shape 的数据量较大时,计算开销将难以接受。

而当 any_shape 的 geo 列有空间索引时,该语句会首先用空间索引过滤掉绝大部分和该线绝对不相交的数据,最终读到内存的还是会有部分可能相交的,因此还需要进行一次计算。这样空间索引就以很小的代价快速过滤掉了大部分不可能相交的数据,最终进行精确过滤的只有少部分,极大的降低了计算开销。


交流图数据库技术?加入 Nebula 交流群请先填写下你的 Nebula 名片,Nebula 小助手会拉你进群~~

Geospatial Data 在 Nebula Graph 中的实践的更多相关文章

  1. 分布式图数据库 Nebula Graph 的 Index 实践

    导读 索引是数据库系统中不可或缺的一个功能,数据库索引好比是书的目录,能加快数据库的查询速度,其实质是数据库管理系统中一个排序的数据结构.不同的数据库系统有不同的排序结构,目前常见的索引实现类型如 B ...

  2. Nebula Graph 的 Ansible 实践

    本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow & 看大厂图数据库技术实践 背景 在 Nebula-Graph 的日常测试中,我们会经常在 ...

  3. 分布式图数据库 Nebula Graph 中的集群快照实践

    1 概述 1.1 需求背景 图数据库 Nebula Graph 在生产环境中将拥有庞大的数据量和高频率的业务处理,在实际的运行中将不可避免的发生人为的.硬件或业务处理错误的问题,某些严重错误将导致集群 ...

  4. Nebula Graph 在网易游戏业务中的实践

    本文首发于 Nebula Graph Community 公众号 当游戏上知识图谱,网易游戏是如何应对大规模图数据的管理问题,Nebula Graph 又是如何帮助网易游戏落地游戏内复杂的图的业务呢? ...

  5. Nebula Graph 在微众银行数据治理业务的实践

    本文为微众银行大数据平台:周可在 nMeetup 深圳场的演讲这里文字稿,演讲视频参见:B站 自我介绍下,我是微众银行大数据平台的工程师:周可,今天给大家分享一下 Nebula Graph 在微众银行 ...

  6. 解析 Nebula Graph 子图设计及实践

    本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 前言 在先前的 Query Engine 源码解析中,我们介绍了 2.0 ...

  7. 图计算 on nLive:Nebula 的图计算实践

    本文首发于 Nebula Graph Community 公众号 在 #图计算 on nLive# 直播活动中,来自 Nebula 研发团队的 nebula-plato 维护者郝彤和 nebula-a ...

  8. 图数据库 Nebula Graph TTL 特性

    导读 身处在现在这个大数据时代,我们处理的数据量需以 TB.PB, 甚至 EB 来计算,怎么处理庞大的数据集是从事数据库领域人员的共同问题.解决这个问题的核心在于,数据库中存储的数据是否都是有效的.有 ...

  9. 图数据库 Nebula Graph 的数据模型和系统架构设计

    Nebula Graph:一个开源的分布式图数据库.作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,而且能够提供极高的 ...

  10. 图数据库|基于 Nebula Graph 的 BetweennessCentrality 算法

    本文首发于 Nebula Graph Community 公众号 ​在图论中,介数(Betweenness)反应节点在整个网络中的作用和影响力.而本文主要介绍如何基于 Nebula Graph 图数据 ...

随机推荐

  1. 浅浅的源码剖析grpc-go(一)

    最近在学习 rpc 相关的知识,如果让我去从头设计一个 rpc,我从使用者的角度出发,究竟需要去做一下什么工作? 第一,RPC 本质上就是一个远程调用,那肯定就需要通过网络来传输数据.虽然传输协议可以 ...

  2. NetCore高级系列文章03---中间件

    .net web 一路发展过来,经历了 .net webfrom. .net Mvc ..net core不论哪种架构,都会对用户的请求到达服务器后经历一系列类似于管道的处理.在.net webfro ...

  3. vim 从嫌弃到依赖(20)——global 命令

    在前面的文章中,我们介绍了如何进行查找和替换,而替换是建立在查找基础之上的一个简单的应用,它只是将匹配文本修改为另一个.那么vim中还能针对匹配上的文本做哪些操作呢?在本篇文章中我们来对这个问题进行探 ...

  4. LyScript 插件实现UPX寻找入口

    LyScript 插件可实现对压缩壳的快速脱壳操作,目前支持两种脱壳方式,一种是运用API接口自己编写脱壳过程,另一种是直接加载现有的脱壳脚本运行脱壳. 插件地址:https://github.com ...

  5. 从嘉手札<2023-11-13>

    1. 很多时候 成功并不等同于成长 成功是很多因素复合形成的一种结果 而并不等同于一个人阅历的丰富.认知的提高 2. 我一直认为 世界不属于投机者 也不属于堕落者 信念感在这个大数据泛滥.碎片化汹涌的 ...

  6. 戴尔R7920工作站利用PVE开启vGPU,实现工作站虚拟化(ShareStation)

    介绍 本文介绍了使用Proxmox VE(PVE) + DoraCloud,将一台Dell R7920图形工作站(配置有NVIDIA RTX A6000显卡)实现工作站虚拟化.可以满足多个设计用户同时 ...

  7. [ Skill ] append1, append, nconc, tconc, lconc, cons 效率对比

    https://www.cnblogs.com/yeungchie/ 先说结论:cons > tconc, lconc >> nconc > append1, append a ...

  8. Windows—通过Navicat导入MySQL示例数据库employees

    Navicat是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL.Oracle.PostgreSQL.SQLite.SQL Server.MariaDB .MongoDB 等不同类型的数据 ...

  9. CF1878C Vasilije in Cacak 题解

    题目传送门 简化题意 有 \(t\) 组询问,每次询问是否能从 \(1 \sim n\) 中选择 \(k\) 个数使得它们的和为 \(x\). 解法 考虑临界情况,从 \(1 \sim n\) 中选择 ...

  10. CF1823D Unique Palindromes

    题目链接 题解 知识点:构造. 首先反证法容易证明一个结论:每次增加一个字符,本质不同的回文子串至多增加一个. 那么无解的条件就是,\(c_i - c_{i-1} > x_i -x_{i-1}\ ...