1. 向Grok3提问
- 提问:创建省份 城市 区域 乡镇街道 知识图谱,要求能够互相推理
- 提问:使用NebulaGraph构建以上知识图谱
接下来大都是GROK的回答,我们来实践一遍。AI极大加快了开发效率。
2. 创建图空间
在 NebulaGraph 中,所有数据存储在图空间(Space)中。先创建一个图空间:
# 长度放大,某些乡镇过长导致无法插入
CREATE SPACE `AddressGraph` (partition_num = 10, vid_type = FIXED_STRING(128)) COMMENT = "行政区划知识图谱"
3. 定义标签(Tag)
实体类型:Province(省份)、City(城市)、District(区域)、Street(乡镇街道)。
每个标签可以附加属性,例如名称。
CREATE TAG Province(name string);
CREATE TAG City(name string);
CREATE TAG District(name string);
CREATE TAG Street(name string);
4. 定义边类型(Edge Type)
关系类型:hasPart(包含)、partOf(属于)。
边可以附加属性。
CREATE EDGE hasPart (relationship_type string);
CREATE EDGE partOf (relationship_type string);
5. 插入数据
以之前提到的广东省为例,插入节点和边数据。
5.1 插入节点(Vertices)
每个实体需要一个唯一的 VID(顶点 ID),这里用字符串表示。
INSERT VERTEX Province(name) VALUES "广东省":("广东省");
INSERT VERTEX City(name) VALUES "广州市":("广州市");
INSERT VERTEX City(name) VALUES "深圳市":("深圳市");
INSERT VERTEX District(name) VALUES "天河区":("天河区");
INSERT VERTEX District(name) VALUES "越秀区":("越秀区");
INSERT VERTEX District(name) VALUES "南山区":("南山区");
INSERT VERTEX District(name) VALUES "福田区":("福田区");
INSERT VERTEX Street(name) VALUES "珠江新城街道":("珠江新城街道");
INSERT VERTEX Street(name) VALUES "天河北街道":("天河北街道");
INSERT VERTEX Street(name) VALUES "北京路街道":("北京路街道");
INSERT VERTEX Street(name) VALUES "人民街道":("人民街道");
INSERT VERTEX Street(name) VALUES "粤海街道":("粤海街道");
INSERT VERTEX Street(name) VALUES "南头街道":("南头街道");
INSERT VERTEX Street(name) VALUES "华强北街道":("华强北街道");
INSERT VERTEX Street(name) VALUES "福保街道":("福保街道");
5.2 插入边(Edges)
定义层级关系。
INSERT EDGE hasPart(relationship_type) VALUES "广东省" -> "广州市":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "广东省" -> "深圳市":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "广州市" -> "广东省":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "深圳市" -> "广东省":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "广州市" -> "天河区":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "广州市" -> "越秀区":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "深圳市" -> "南山区":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "深圳市" -> "福田区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "天河区" -> "广州市":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "越秀区" -> "广州市":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "南山区" -> "深圳市":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "福田区" -> "深圳市":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "天河区" -> "珠江新城街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "天河区" -> "天河北街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "越秀区" -> "北京路街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "越秀区" -> "人民街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "南山区" -> "粤海街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "南山区" -> "南头街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "福田区" -> "华强北街道":("行政隶属");
INSERT EDGE hasPart(relationship_type) VALUES "福田区" -> "福保街道":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "珠江新城街道" -> "天河区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "天河北街道" -> "天河区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "北京路街道" -> "越秀区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "人民街道" -> "越秀区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "粤海街道" -> "南山区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "南头街道" -> "南山区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "华强北街道" -> "福田区":("行政隶属");
INSERT EDGE partOf(relationship_type) VALUES "福保街道" -> "福田区":("行政隶属");
6. 查询与推理
NebulaGraph 使用 nGQL(Nebula Graph Query Language)进行查询,支持路径查找和多跳查询,非常适合实现推理。
- 查询示例1:珠江新城街道属于哪个省份?
# AI这块生成还不行,语法错误
GO FROM "珠江新城街道" OVER partOf YIELD id($$) AS district |
GO FROM $-.district OVER partOf YIELD id($$) AS city |
GO FROM $-.city OVER partOf YIELD id($$) AS province
解释:从“珠江新城街道”开始,沿 partOf 边向上查找,经过区域(天河区)、城市(广州市),最终到达省份(广东省)。
输出:“广东省”
- 查询示例2:广东省包含哪些乡镇街道?
GO FROM "广东省" OVER hasPart YIELD id($$) AS city |
GO FROM $-.city OVER hasPart YIELD id($$) AS district |
GO FROM $-.district OVER hasPart YIELD id($$) AS street
解释:从“广东省”开始,沿 hasPart 边向下查找,经过城市、区域,最终到达所有乡镇街道。
输出:“珠江新城街道”, “天河北街道”, “北京路街道”, …
- 查询示例3:天河区的所有上级实体
GO 2 STEPS FROM "天河区" OVER partOf YIELD id($$)
UNION
GO 1 STEPS FROM "天河区" OVER partOf YIELD id($$)
解释:返回距离天河区一跳与二跳。
输出:“广州市”, “广东省”
- 查询示例4: 获取所有顶点和边
GET SUBGRAPH WITH PROP FROM "广州市" YIELD VERTICES AS nodes, EDGES AS relationships
GET SUBGRAPH WITH PROP FROM "越秀区" YIELD VERTICES AS nodes, EDGES AS relationships
- 查询实例5:获取上海市下属行政单位
GET SUBGRAPH WITH PROP 2 STEPS FROM "上海市" YIELD vertices AS nodes, edges AS relationships;
为什么要构建该知识图谱,为了后续的地址标准化~~