MATCH 查询模式和语法详解

下面我将详细介绍如何在 Nebula Graph 中执行多跳查询(2跳、3跳、4跳等),包括数据准备、常用 MATCH 查询模式和语法详解。

一、扩展测试数据

首先我们扩展测试数据,构建更复杂的图结构:

-- 创建更多Tag和Edge类型
CREATE TAG IF NOT EXISTS skill(name string, level int);
CREATE EDGE IF NOT EXISTS friend(degree string);
CREATE EDGE IF NOT EXISTS learn(years int);

-- 插入更多人物顶点
INSERT VERTEX person(name, age) VALUES 
    "p102":("王五", 35),
    "p103":("赵六", 40),
    "p104":("钱七", 28),
    "p105":("孙八", 45);

-- 插入更多公司顶点
INSERT VERTEX company(name) VALUES 
    "c202":("字节跳动"),
    "c203":("美团"),
    "c204":("拼多多");

-- 插入技能顶点
INSERT VERTEX skill(name, level) VALUES 
    "s300":("Java", 3),
    "s301":("Python", 4),
    "s302":("Go", 2),
    "s303":("SQL", 5);

-- 添加更多工作关系
INSERT EDGE works(start_date, end_date) VALUES 
    "p102"->"c202":("2017-03-01", ""),
    "p103"->"c203":("2016-07-01", "2021-05-31"),
    "p104"->"c204":("2019-09-01", ""),
    "p105"->"c200":("2010-01-01", "2018-12-31");

-- 添加朋友关系
INSERT EDGE friend(degree) VALUES 
    "p100"->"p101":("close"),
    "p100"->"p102":("normal"),
    "p101"->"p103":("close"),
    "p102"->"p104":("normal"),
    "p103"->"p105":("close");

-- 添加学习技能关系
INSERT EDGE learn(years) VALUES 
    "p100"->"s300":(5),
    "p101"->"s301":(3),
    "p102"->"s300":(4),
    "p103"->"s302":(2),
    "p104"->"s303":(6),
    "p105"->"s300":(7);

二、多跳查询语法详解

1. 基础 MATCH 语法结构

MATCH <pattern> [WHERE <conditions>] RETURN <output> [LIMIT <n>]

2. 跳数表示方法

  • :edge_type{minHop: m, maxHop: n}:指定跳数范围

  • :edge_type*n:固定n跳

  • :edge_type+:1跳或更多

  • :edge_type:默认1跳

三、常用多跳查询示例

1. 2跳查询

示例1:查询某人的朋友的朋友

MATCH (v:person)-[:friend*2]->(v2:person) 
WHERE id(v) == "p100"
RETURN id(v) AS source, id(v2) AS target;

示例2:查询在某公司工作过的人的朋友

MATCH (c:company)<-[:works]-(v:person)-[:friend]->(v2:person)
WHERE c.company.name == "阿里巴巴"
RETURN v.person.name AS employee, v2.person.name AS friend;

2. 3跳查询

示例1:查询某人的朋友的朋友的朋友

MATCH (v:person)-[:friend*3]->(v2:person)
WHERE id(v) == "p100"
RETURN id(v) AS source, id(v2) AS target;

示例2:查询在某公司工作过的人的朋友掌握的所有技能

MATCH (c:company)<-[:works]-(v:person)-[:friend]->(v2:person)-[:learn]->(s:skill)
WHERE c.company.name == "腾讯"
RETURN v.person.name AS employee, 
       v2.person.name AS friend, 
       s.skill.name AS skill, 
       s.skill.level AS level;

3. 4跳查询

示例:查询某人的朋友的朋友的朋友的朋友

MATCH (v:person)-[:friend*4]->(v2:person)
WHERE id(v) == "p100"
RETURN id(v) AS source, id(v2) AS target;

4. 可变跳数查询

示例1:查询1-3跳内的所有朋友

MATCH (v:person)-[:friend*1..3]->(v2:person)
WHERE id(v) == "p100"
RETURN id(v) AS source, id(v2) AS target, length(p) AS hops;

示例2:查询至少2跳的工作关系路径

MATCH (v1:person)-[:works*2..]->(v2:company)
RETURN v1.person.name AS person, id(v2) AS company;

四、复杂路径查询

1. 路径过滤

示例:查找从张三到孙八的所有路径(最多4跳)

MATCH p=(v1:person)-[:friend|works*1..4]->(v2:person)
WHERE v1.person.name == "张三" AND v2.person.name == "孙八"
RETURN p;

2. 最短路径查询

示例:查找张三到孙八的最短朋友路径

FIND SHORTEST PATH FROM "p100" TO "p105" OVER friend YIELD path AS p;

3. 全路径查询

示例:查找所有人与公司之间的3跳路径

MATCH p=(v:person)-[*3]-(c:company)
RETURN p LIMIT 10;

五、性能优化建议

  1. 使用索引加速查询

CREATE TAG INDEX person_name_index ON person(name(20));
REBUILD TAG INDEX person_name_index;
  1. 限制跳数范围:避免无限制的*查询

  2. 使用WHERE子句尽早过滤

MATCH (v:person)-[:friend*2]->(v2:person)
WHERE v.person.age > 30 AND v2.person.age < 40
RETURN v, v2;
  1. 限制返回结果数量

MATCH (v)-[*3]->(v2) RETURN v, v2 LIMIT 100;
  1. 使用PROFILE分析查询

PROFILE MATCH (v)-[*3]->(v2) RETURN v, v2 LIMIT 100;

六、常见问题解决

  1. 查询超时:增加超时设置

-- 在nebula-graphd配置中修改
-- --storage_client_timeout_ms=60000
  1. 内存不足:限制跳数和结果集大小

  2. 无结果返回:检查数据是否存在,跳数是否足够

  3. 性能慢:创建适当的索引,优化查询模式

通过以上示例和技巧,您可以构建复杂的多跳查询来分析图数据中的深层关系。实际应用中,建议根据业务需求设计合适的图模型和查询模式。

posted @ 2025-07-28 11:27  郭慕荣  阅读(26)  评论(0)    收藏  举报