跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

子图过程(algo.subgraph)

algo.subgraph是由官方algo插件提供的内置命名过程,用于在持久图上按多源 BFS 方式提取子图。可以指定起始点、遍历步数、边类型、遍历方向,以及边和点的属性过滤条件。

KILL QUERY无法立即中止正在运行的algo.subgraph过程。其底层的 BFS 循环会在后台继续执行,直到遍历自然结束,即达到最大遍历步数或没有可继续扩展的点。

适用场景

  • 从一个或多个源点按跳数提取局部子图。
  • 仅沿指定边类型提取子图。
  • 在提取过程中按边属性/点属性过滤结果。

前提条件

  • algo插件必须已加载到当前 Catalog。algo插件不会随服务启动自动加载。首次使用前,请使用拥有ADMIN角色的用户执行:

    CREATE PLUGIN IF NOT EXISTS algo
    

    加载后,可以执行SHOW PLUGIN algo检查插件状态。请在相关服务上的plugin_status均为Valid后调用algo.subgraph。状态字段的详细说明,请参见 SHOW PLUGIN / PLUGINS。

  • 传入algo.subgraph的graph_name必须是已存在的持久图(通过CREATE GRAPH创建)。

工作机制

当steps为0时,algo.subgraph不执行扩展,直接返回实际存在的源点,且不返回边。

当steps大于0时,algo.subgraph最多按以下阶段执行 BFS:

  • 前steps个阶段:从源点正常扩展,每一跳发现新点和新边。
  • 如果第steps个阶段结束后仍有新发现的点,则再执行一个阶段,仅在已遍历的点集合内部补充连通的边,不向外扩展寻找新点。

如果某个阶段结束后没有可继续扩展的点,遍历会提前结束。

因此,输出子图中的每条边两端都在返回的点集合中。

过程签名

algo.subgraph(
  graph_name STRING,
  src_ids LIST<INT64>,
  steps UINT64,
  edge_types LIST<STRING>,
  direction STRING,
  edge_filters LIST<STRING>,
  node_filters LIST<STRING>
)

最少传 3 个参数,后 4 个参数可省略。

参数说明

参数 是否必填 说明
graph_name 是 Catalog 中已存在的持久图名称。
src_ids 是 源点元素 ID 列表(必须是INT64),不能为空。重复 ID 会自动去重。
steps 是 最大遍历步数。0表示不扩展,仅返回源点(若存在)。
edge_types 否 允许遍历的边类型列表。省略或传空列表时表示不过滤边类型。
direction 否 遍历方向:outgoing、incoming、bidirect。默认bidirect。
edge_filters 否 边属性过滤表达式列表,多个条件按 AND 关系生效。
node_filters 否 对遍历中新发现的点应用的属性过滤表达式列表,多个条件按 AND 关系生效。源点不受此参数过滤。未通过过滤的点不会继续参与扩展,其关联边也不会出现在结果中。

Important

src_ids需要传节点内部元素 ID(element_id(v)),不是业务属性值(例如v.id)。

过滤表达式

edge_filters和node_filters的每一项是一个字符串表达式。仅支持属性与常量的简单比较:=, <>, >, <, >=, <=。例如:"weight >= 2"、"age <= 30"。

Note

每个过滤表达式只能包含一个简单比较操作(例如"weight >= 2")。不支持在单一表达式内部使用布尔逻辑组合(如 AND/OR),也不支持带类型前缀的属性(例如Person.age <= 30)。若需应用多个过滤条件,请将它们作为独立的元素放入列表中进行传递(例如["weight >= 2", "age <= 30"])。

返回值

过程返回两列:

  • nodes: LIST<NODE>,提取出的点集合。
  • edges: LIST<EDGE>,提取出的边集合。

示例

以下示例基于示例数据集。

示例 1:最小参数调用(默认双向、不过滤边类型)

'''
USE movie
MATCH (v@Movie) WHERE v.id = 1
RETURN [element_id(v)] AS ids
NEXT
USE movie
CALL algo.subgraph("movie", ids, CAST(1 AS UINT64))
YIELD nodes, edges
RETURN size(nodes) AS node_count, size(edges) AS edge_count
'''

返回:

+------------+------------+
| node_count | edge_count |
+------------+------------+
| 43         | 42         |
+------------+------------+

示例 2:仅沿WithGenre出边遍历 2 跳

'''
USE movie
MATCH (v@Movie) WHERE v.id = 1
RETURN [element_id(v)] AS ids
NEXT
USE movie
CALL algo.subgraph("movie", ids, CAST(2 AS UINT64), ["WithGenre"], "outgoing")
YIELD nodes, edges
RETURN size(nodes) AS node_count, size(edges) AS edge_count
'''

返回:

+------------+------------+
| node_count | edge_count |
+------------+------------+
| 23         | 22         |
+------------+------------+

示例 3:边过滤 + 点过滤

'''
USE movie
MATCH (v@Movie) WHERE v.id >= 1 AND v.id <= 10
RETURN [element_id(v)] AS ids
NEXT
USE movie
CALL algo.subgraph(
  "movie",
  ids,
  CAST(3 AS UINT64),
  ["Watch"],
  "incoming",
  ["id >= 10"],
  ["rate < 5"]
)
YIELD nodes, edges
RETURN size(nodes) AS node_count, size(edges) AS edge_count
'''

返回:

+------------+------------+
| node_count | edge_count |
+------------+------------+
| 1          | 0          |
| 1          | 0          |
| 1          | 0          |
| 1          | 0          |
| 1          | 0          |
+------------+------------+

更多CALL语法信息,请参见使用 CALL 调用命名过程。