Skip to Content

Match 子句

MATCH 子句用于在图数据库中搜索模式。它允许你查找符合特定条件的节点、边和路径。

匹配节点

匹配单标签节点

查找具有特定标签的所有节点。此查询返回所有标签为 person 的节点。

MATCH (p:Person) RETURN p;

输出:

+-------------------------------------------------------+ | p | +=======================================================+ | {_ID: 0, _LABEL: Person, name: marko, age: 29} | +-------------------------------------------------------+ | {_ID: 1, _LABEL: Person, name: vadas, age: 27} | +-------------------------------------------------------+ | {_ID: 2, _LABEL: Person, name: josh, age: 32} | +-------------------------------------------------------+ | {_ID: 3, _LABEL: Person, name: peter, age: 35} | +-------------------------------------------------------+

匹配具有多个标签的节点

查找具有任意指定标签的节点。此查询返回所有标记为 personsoftware 的节点。

注意:与 Neo4j 不同,NeuG 不支持多标签节点。在 Neo4j 中,(p:Person:Software) 表示同时具有 personsoftware 标签的节点。而在 NeuG 中,此语法表示具有 personsoftware 标签的节点的并集。

MATCH (p:Person:Software) RETURN p;

输出:

+-----------------------------------------------------------------------------+ | p | +=============================================================================+ | {_ID: 0, _LABEL: Person, name: marko, age: 29} | +-----------------------------------------------------------------------------+ | {_ID: 1, _LABEL: Person, name: vadas, age: 27} | +-----------------------------------------------------------------------------+ | {_ID: 2, _LABEL: Person, name: josh, age: 32} | +-----------------------------------------------------------------------------+ | {_ID: 3, _LABEL: Person, name: peter, age: 35} | +-----------------------------------------------------------------------------+ | {_ID: 72057594037927936, _LABEL: Software, name: lop, lang: java} | +-----------------------------------------------------------------------------+ | {_ID: 72057594037927937, _LABEL: Software, name: ripple, lang: java} | +-----------------------------------------------------------------------------+

匹配任意标签的节点

无需指定标签即可匹配节点。NeuG 支持无显式标签的查询,并在编译期间根据已定义的模式约束自动推断未知标签。

MATCH (p) RETURN p;

输出:

+-----------------------------------------------------------------------------+ | p | +=============================================================================+ | {_ID: 0, _LABEL: Person, name: marko, age: 29} | +-----------------------------------------------------------------------------+ | {_ID: 1, _LABEL: Person, name: vadas, age: 27} | +-----------------------------------------------------------------------------+ | {_ID: 2, _LABEL: Person, name: josh, age: 32} | +-----------------------------------------------------------------------------+ | {_ID: 3, _LABEL: Person, name: peter, age: 35} | +-----------------------------------------------------------------------------+ | {_ID: 72057594037927936, _LABEL: Software, name: lop, lang: java} | +-----------------------------------------------------------------------------+ | {_ID: 72057594037927937, _LABEL: Software, name: ripple, lang: java} | +-----------------------------------------------------------------------------+

按条件匹配节点

除了标签约束外,您还可以指定基于属性的过滤条件。

MATCH (p:Person {name: 'marko'}) RETURN p;

输出:

+-------------------------------------------------------+ | p | +=======================================================+ | {_ID: 0, _LABEL: Person, name: marko, age: 29} | +-------------------------------------------------------+

匹配边

匹配具有单一标签的边

MATCH (p:Person)-[k:KNOWS]->(f:Person) RETURN k;

输出:

+------------------------------------------------------------------------------------------------------+ | k | +======================================================================================================+ | {_ID: 1, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 1, weight: 0.5} | +------------------------------------------------------------------------------------------------------+ | {_ID: 2, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 2, weight: 1.0} | +------------------------------------------------------------------------------------------------------+

匹配具有多个标签的边

MATCH (p:Person)-[k:KNOWS|CREATED]->(f) RETURN k;

输出:

+--------------------------------------------------------------------------------------------------------------------------------------+ | k | +======================================================================================================================================+ | {_ID: 1, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 1, weight: 0.5} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 2, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 2, weight: 1.0} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103806595072, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 0, _DST_ID: 72057594037927936, weight: 0.4} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103808692224, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 2, _DST_ID: 72057594037927936, weight: 0.4} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103808692225, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 2, _DST_ID: 72057594037927937, weight: 1.0} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103809740800, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 3, _DST_ID: 72057594037927936, weight: 0.2} | +--------------------------------------------------------------------------------------------------------------------------------------+

匹配任意标签的边

MATCH (p:Person)-[k]->(f) RETURN k;

输出:

+--------------------------------------------------------------------------------------------------------------------------------------+ | k | +======================================================================================================================================+ | {_ID: 1, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 1, weight: 0.5} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 2, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 2, weight: 1.0} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103806595072, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 0, _DST_ID: 72057594037927936, weight: 0.4} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103808692224, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 2, _DST_ID: 72057594037927936, weight: 0.4} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103808692225, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 2, _DST_ID: 72057594037927937, weight: 1.0} | +--------------------------------------------------------------------------------------------------------------------------------------+ | {_ID: 1103809740800, _LABEL: CREATED, _SRC_LABEL: Person, _DST_LABEL: Software, _SRC_ID: 3, _DST_ID: 72057594037927936, weight: 0.2} | +--------------------------------------------------------------------------------------------------------------------------------------+

按条件匹配边

根据边的属性过滤边。

MATCH (p:Person)-[k:KNOWS {weight: 1.0}]->(f:Person) RETURN k;

输出:

+------------------------------------------------------------------------------------------------------+ | k | +======================================================================================================+ | {_ID: 2, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 0, _DST_ID: 2, weight: 1.0} | +------------------------------------------------------------------------------------------------------+

匹配重复路径

NeuG 支持可变长度的重复路径探索,这是图查询中的常见功能。

匹配可变长度的重复路径

查找具有可变跳数的路径。此查询返回所有由 1 条或 2 条边组成的路径。

MATCH (p:Person)-[k*1..2]->(f) RETURN k;

匹配带源条件的重复路径

根据源节点的属性指定过滤条件。此查询查找从名称为 ‘marko’ 的节点出发的 1 跳或 2 跳路径。

MATCH (p:Person {name: 'marko'})-[k*1..2]->(f) RETURN k;

匹配带有目标条件的重复路径

根据目标节点的属性指定过滤条件。该查询查找终点为名为 ‘josh’ 的节点的路径。

MATCH (p:Person {name: 'marko'})-[k*1..2]->(f {name: 'josh'}) RETURN k;

输出:

+---------------------------------------------------------------------------------------------------------------------------------------------------+ | k | +===================================================================================================================================================+ | {_ID: 2, _LABEL: Person}, {_ID: 2097152, _LABEL: KNOWS, _SRC_LABEL: Person, _DST_LABEL: Person, _SRC_ID: 2, _DST_ID: 0}, {_ID: 0, _LABEL: Person} | +---------------------------------------------------------------------------------------------------------------------------------------------------+

匹配带有边条件的重复路径

参考 Kuzu 规范 ,NeuG 还支持在路径中对每条边进行属性过滤。

此查询要求路径中的每条边都满足约束 r.weight < 1.0

MATCH (p:Person {name: 'marko'})-[k:KNOWS*1..2 (r, _ | WHERE r.weight <= 1.0)]->(f:Person) RETURN k;

匹配 Trail 路径

使用 TRAIL 选项,您可以进一步限制重复路径,确保不重复任何边,从而保证路径扩展迭代能够正常终止,避免陷入无限循环。

MATCH (p:Person {name: 'marko'})-[k:KNOWS* TRAIL 1..2]->(f:Person) RETURN k;

匹配简单路径

使用 ACYCLIC 选项可以进一步限制重复路径,确保不重复访问任何节点,从而保证输出简单路径。

MATCH (p:Person {name: 'marko'})-[k:KNOWS* ACYCLIC 1..2]->(f:Person) RETURN k;

匹配无权最短路径

指定 SHORTEST 选项以输出两个给定节点之间的无权最短路径。

MATCH (p:Person {name: 'marko'})-[k:KNOWS* SHORTEST 1..2]->(f:Person {name: 'josh'}) RETURN k;

匹配模式

MATCH 子句支持复杂的模式匹配,能够以多种方式组合节点、边和条件,从而表达复杂的图查询。

以下是各类图查询基准测试中广泛使用的几种经典图查询模式:

  • 三角形模式
MATCH (a:Person)-[:CREATED]->(b:Software), (c:Person)-[:CREATED]->(b:Software), (a:Person)-[:KNOWS]->(c:Person) WHERE a.name <> b.name AND b.name <> c.name RETURN count(*);
  • 正方形模式
MATCH (a:Person)-[:CREATED]->(b:Software), (c:Person)-[:CREATED]->(b:Software), (a:Person)-[:KNOWS]->(d:Person), (c:Person)<-[:KNOWS]-(d:Person) WHERE a.name <> b.name AND b.name <> c.name AND c.name <> d.name RETURN count(*);
  • 长路径
MATCH (a:Person)-[:KNOWS]->(b:Person), (b:Person)-[:KNOWS]->(c:Person), (c:Person)-[:CREATED]->(d:Software), (d:Software)<-[:CREATED]-(e:Person), (e:Person)-[:KNOWS]->(f:Person) WHERE a.name <> b.name AND b.name <> c.name AND c.name <> d.name AND d.name <> e.name RETURN count(*);
  • 团路径
MATCH (a:Person)-[:CREATED]->(b:Software), (c:Person)-[:CREATED]->(b:Software), (a:Person)-[:KNOWS]->(d:Person), (c:Person)<-[:KNOWS]-(d:Person), (a:Person)-[:KNOWS]->(c:Person), (d:Person)-[:CREATED]->(b:Software) WHERE a.name <> b.name AND b.name <> c.name AND c.name <> d.name RETURN count(*);

可选匹配

OPTIONAL MATCH 子句允许您匹配图中可能存在也可能不存在的模式,对于未匹配的模式部分返回 null

以下是可选匹配的使用方法:

MATCH (a:Person)-[:KNOWS]->(b:Person) OPTIONAL MATCH (b:Person)-[:CREATED]->(c:Software) RETURN a.name, b.name, c.name

在上述输出结果中,对于每个 (a, b) 对:

  • 如果 b 存在相连的节点 c,则返回所有 (a, b, c) 三元组。例如,对于 (‘marko’, ‘josh’),对应的三元组为 {(‘marko’, ‘josh’, ‘lop’), (‘marko’, ‘josh’, ‘ripple’)}。
  • 如果 b 没有相连的节点 c,则为当前的 (a, b) 对保留一行 c=null 的记录。例如,对于 (‘marko’, ‘vadas’),输出的三元组为 {(‘marko’, ‘vadas’, null)}。

这正是 OPTIONAL MATCH 子句的主要目的——即使可选模式未匹配,也能保留主 MATCH 产生的行。

Last updated on