创建和使用图分析引擎

更新时间:2025-04-29 02:04:55

本文介绍如何在云原生数据仓库 AnalyticDB PostgreSQL 版中创建和使用图分析引擎。

什么是Cypher

Cypher是一种声明式的查询语言。作为通过开放Cypher项目提供的开源语言,Cypher在设计上类似于SQL,但专门针对图数据结构做了优化。它具有直观且接近自然语言的语法,能够以清晰简洁的方式表达节点之间的关系和图的匹配模式,为用户提供了一种高效且易用的图数据查询方式。例如:

MATCH (n:nodes)-[r:ARE_CONNECTED_TO]->(o:otherNodes)
RETURN n,r,o

以上Cypher查询通过模式匹配查找图中所有满足条件的节点和关系。其中,(n:nodes)表示带有nodes标签的节点,n为别名,即将带有nodes标签的节点赋给变量n;[r:ARE_CONNECTED_TO]表示带有ARE_CONNECTED_TO标签的关系,r为别名;而(o:otherNodes)表示带有otherNodes标签的目标节点,o为别名。查询最终返回所有符合该模式的源节点、目标节点以及它们之间的关系。

语法介绍

节点语法

Cypher中,使用一对圆括号()表示节点。以下是几种常见节点的表示方式及其含义:

  • ():匿名节点。表示一个匿名且未指定任何标签的节点,通常用于匹配任意节点。

  • (node):带变量的节点。为节点指定一个变量名(如node),以便在查询中引用该节点。

  • (:City):带标签的节点。表示具有City标签的节点。标签的作用类似于关系型数据库中的表名或分类标识,用于筛选特定类型的节点。

  • (city:City):带变量和标签的节点。为节点指定变量名city和标签City,既便于引用,又明确节点类型。

  • (city:City {name: 'Hangzhou'}):带标签(标签以键值对的形式表示)的节点。在节点中添加标签{name: 'Hangzhou'},用于进一步限定节点的特征。这类似于关系型数据库中的WHERE条件,能够精确匹配符合标签值的节点。

  • (city:City {name: 'Hangzhou', province: 'Zhejiang'}):带多个标签的节点。节点可以包含多个标签,支持更复杂的条件筛选。

关系语法

Cypher中,使用一对短划线--表示关系。有向关系则在一端添加箭头,例如 -->。为了进一步描述关系的详细信息,可以使用方括号[],其中可以包含变量、类型和标签等信息。以下是几种常见关系的表示方式及其含义:

  • --:表示一个匿名的、未指定类型的无向关系。

  • -->:表示一个匿名的、未指定类型的有向关系。

  • -[role]->:为关系定义了一个变量role,以便在查询中引用。

  • -[:ACTED_IN]->:指定关系的类型为ACTED_IN,类似于节点中的标签。

  • -[role:ACTED_IN]->:同时定义了关系的变量role和类型ACTED_IN

  • -[role:ACTED_IN {roles: ['Neo']}]->:在关系中添加了标签{roles: ['Neo']},用于描述关系的具体特征。

关系的括号语法和语义与节点的圆括号语法非常相似。

  • 变量:关系中的变量(如role)类似于节点中的变量,用于在查询中引用。

  • 类型:关系的类型(如ACTED_IN)类似于节点的标签,用于分类和筛选特定的关系。

  • 标签:关系的标签(如{roles: ['Neo']})与节点的标签完全等效,支持键值对的形式来描述关系的详细信息。

模式语法

通过结合节点和关系的语法,可构建模式以传递更丰富的信息。以下是一个简单的模式表达式:

(city_from:City {province: 'Zhejiang'})-[:NEXT_TO]-(city_next:City {province: 'Jiangsu'})

该模式表达式含义如下:

  • (city_from:City {province: 'Zhejiang'}):表示一个含City标签的节点,其标签province'Zhejiang',即浙江省的一座城市。

  • (city_next:City {province: 'Jiangsu'}):表示另一个含City标签的节点,其标签province'Jiangsu',即江苏省的一座城市。

  • -[:NEXT_TO]-:表示一条无向边,类型为NEXT_TO,用于描述两座城市在地理位置上的相邻关系。

该模式表达式匹配浙江省和江苏省之间相邻的城市关系。其中:

  • city_from和 city_next分别表示浙江省和江苏省的城市节点。

  • [:NEXT_TO] 表示两座城市之间的地理相邻关系。

版本限制

内核版本为7.2.1.0及以上的AnalyticDB for PostgreSQL7.0版实例。

说明

您可以在控制台实例的基本信息页查看内核小版本。如不满足上述版本要求,需要您升级内核小版本

前提条件

  • 已为实例安装age插件

  • 安装age插件后,需要在数据库中将ag_catalog添加到search_path,以简化查询。以下是两种配置方式:

    • 会话级别设置。

      SET search_path = ag_catalog, public;
    • 数据库级别永久设置。

      ALTER DATABASE <database_name> SET search_path TO ag_catalog,public;
  • (可选)使用初始账号高权限用户RDS_SUPERUSER授权其他用户使用图插件。

    GRANT USAGE ON SCHEMA ag_catalog TO <username>;

创建和使用图分析引擎

创建图

语法

使用create_graph函数创建图。

SELECT create_graph('<graph_name>');

参数说明

graph_name:图的名称。

使用示例

SELECT create_graph('relation');

写入数据

语法

通过调用ag_catalog中的cypher函数,可以编写表达式创建节点和关系。

SELECT * FROM cypher('<graph_name>', $$
  /* 编写Cypher表达式 */
  $$) AS (result_a agtype, result_b agtype);

使用示例

以下示例图包含三个人员节点(张三、李四、王五)和两个公司节点(Company A、Company C)。人员与公司通过EMPLOYED边关联,人员之间通过FRIENDSTEACHER边关联。

image

向图relation中写入数据。

SELECT * FROM cypher('relation', $$
  CREATE (ZhangSan:Person {name: 'Zhang San'})
  CREATE (LiSi:Person {name: 'Li Si'})
  CREATE (WangWu:Person {name: 'Wang Wu'})
  CREATE (company_a:Company {name: 'Company A'})
  CREATE (company_c:Company {name: 'Company C'})
  CREATE (ZhangSan)-[:EMPLOYED]->(company_a)
  CREATE (LiSi)-[:EMPLOYED]->(company_c)
  CREATE (WangWu)-[:EMPLOYED]->(company_a)
  CREATE (ZhangSan)-[:FRIENDS]->(LiSi)
  CREATE (WangWu)-[:TEACHER]->(ZhangSan)
$$) AS (result_a agtype)

查询数据

语法

使用MATCHRETURN语句实现数据的查询。MATCH用于定义需要匹配的图模式,即指定要查找的节点、关系及其属性。RETURN用于指定查询结果中需要返回的内容。

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  WHERE <expression> --可选
  RETURN <variables>
$$) AS (result_a agtype);

查询所有数据

  • 查找所有标签为Person的节点。

    SELECT * FROM cypher('relation', $$
      MATCH (m:Person)
      RETURN m
    $$) AS (result_a agtype)

    结果如下:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
     {"id": 844424930131970, "label": "Person", "properties": {"name": "Li Si"}}::vertex
     {"id": 844424930131971, "label": "Person", "properties": {"name": "Wang Wu"}}::vertex
    (3 rows)
  • 查找所有标签为EMPLOYED的边。

    SELECT * FROM cypher('relation', $$
      MATCH (:Person)-[r:EMPLOYED]->(:Company)
      RETURN r
    $$) AS (result_a agtype);

    结果如下:

                                                                result_a                                                            
    --------------------------------------------------------------------------------------------------------------------------------
     {"id": 1407374883553281, "label": "EMPLOYED", "end_id": 1125899906842625, "start_id": 844424930131969, "properties": {}}::edge
     {"id": 1407374883553282, "label": "EMPLOYED", "end_id": 1125899906842626, "start_id": 844424930131970, "properties": {}}::edge
     {"id": 1407374883553283, "label": "EMPLOYED", "end_id": 1125899906842625, "start_id": 844424930131971, "properties": {}}::edge
    (3 rows)

查询部分数据(过滤数据)

当在图中执行模式匹配并需要返回特定数据时,可以使用WHERE子句对匹配结果进行条件过滤。

  • 查询A公司的所有员工。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person)-[:EMPLOYED]->(a:Company)
      WHERE a.name='Company A'
      RETURN p
    $$) AS (result_a agtype);

    结果如下:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
     {"id": 844424930131971, "label": "Person", "properties": {"name": "Wang Wu"}}::vertex
    (2 rows)
  • 查询王五的学生。

    SELECT * FROM cypher('relation', $$
      MATCH (p1:Person)-[:TEACHER]->(p2:Person)
      WHERE p1.name='Wang Wu'
      RETURN p2
    $$) AS (result_a agtype)

    结果如下:

                                            result_a                                         
    -----------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang San"}}::vertex
    (1 row)

更新数据(节点或边)

对于图中已有的数据(包括节点和关系),可以通过匹配目标对象并使用SET关键字来添加或更新数据,从而完成数据的修改操作。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  SET <property>
  RETURN <variable>
$$) AS (result_a agtype)

使用示例

  • 将张三的姓名改为“Zhang 3”。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person {name:'Zhang San'})
      SET p.name='Zhang 3'
      RETURN p
    $$) AS (result_a agtype);

    更新结果如下:

                                           result_a                                        
    ---------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang 3"}}::vertex
    (1 row)
  • 为张三增加性别标签male。

    SELECT * FROM cypher('relation', $$
      MATCH (p:Person {name: 'Zhang 3'})
      SET p.gender = 'male'
      RETURN p
    $$) AS (result_a agtype);

    更新结果如下:

                                                    result_a                                                 
    ---------------------------------------------------------------------------------------------------------
     {"id": 844424930131969, "label": "Person", "properties": {"name": "Zhang 3", "gender": "male"}}::vertex
    (1 row)

删除数据

删除标签

当不再需要节点或边的标签时,可以使用REMOVE关键字删除该标签。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  REMOVE <property>
$$) AS (result_a agtype);

使用示例

删除“张三”的性别标签。

SELECT * FROM cypher('relation', $$
  MATCH (p:Person {name: 'Zhang 3'})
  REMOVE p.gender
  RETURN p
$$) AS (result_a agtype);

删除节点

使用DELETE关键字删除节点或边。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DELETE <variable>
$$) AS (result_a agtype);

使用示例

先添加一个节点“赵六”,然后删除该节点。

-- 添加节点“赵六”
SELECT * FROM cypher('relation', $$
  CREATE (:Person {name: 'Zhao Liu'})
$$) AS (result_a agtype)

-- 删除该节点
SELECT * FROM cypher('relation', $$
  MATCH(p:Person {name: 'Zhao Liu'})
  DELETE p
$$) AS (result_a agtype)
说明

如果某个节点存在边,则不允许直接删除该节点。可以使用DETACH DELETE语句同时删除该节点和其边关系

删除边

先添加一个节点“赵六”,然后为该节点添加一个边,使其就职于公司C,最后删除就职关系。删除时,需在WHERE字句中同时指定人员名称和公司名称。

-- 添加节点“赵六”以及其就职于公司C
SELECT * FROM cypher('relation', $$
  CREATE (ZhaoLiu:Person {name: 'Zhao Liu'})
  CREATE (ZhaoLiu)-[:EMPLOYED]->(:Company {name: 'Company C'})
$$) AS (result_a agtype);

-- 同时删除赵六与公司C的就职关系
SELECT * FROM cypher('relation', $$
  MATCH (p:Person)-[r:EMPLOYED]->(c:Company)
  WHERE p.name='Zhao Liu' AND c.name='Company C'
  DELETE r
$$) AS (result_a agtype);

删除节点和相应边

如果某个节点存在相应的边,则不允许直接删除该节点。可以使用DETACH DELETE语句同时删除该节点和其边关系。

语法

SELECT * FROM cypher('<graph_name>', $$
  MATCH <patterns>
  DETACH DELETE <variable>
$$) AS (result_a agtype);

使用示例

先添加一个节点“赵六”,然后为该节点添加一个边,使其就职于公司C,最后删除就职关系以及节点“赵六”。

-- 创建赵六节点,以及其就职于公司C的关系
SELECT * FROM cypher('relation', $$
  CREATE (ZhaoLiu:Person {name: 'Zhao Liu'})
  CREATE (ZhaoLiu)-[:EMPLOYED]->(:Company {name: 'Company C'})
$$) AS (result_a agtype);

-- 删除赵六节点以及其关联的边
SELECT * FROM cypher('relation', $$
  MATCH (p:Person {name: 'Zhao Liu'})
  DETACH DELETE p
$$) AS (result_a agtype);
  • 本页导读 (1)
  • 什么是Cypher
  • 语法介绍
  • 节点语法
  • 关系语法
  • 模式语法
  • 版本限制
  • 前提条件
  • 创建和使用图分析引擎
  • 创建图
  • 写入数据
  • 查询数据
  • 更新数据(节点或边)
  • 删除数据
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等