Skip to content

Neo4j 常见 Cypher 查询

基础查询

查询所有节点

功能描述:查询数据库中的所有节点,返回完整的节点数据。

语法说明MATCH (n) 匹配所有节点,RETURN n 返回匹配到的节点。

使用场景:适用于小型数据库或需要查看所有数据的情况,在大型数据库中使用可能会导致性能问题。

注意事项:在生产环境中,应避免使用此查询,因为它会返回所有节点,可能导致内存溢出。

cypher
MATCH (n) RETURN n;

查询特定标签的节点

功能描述:查询具有特定标签(如 Person)的所有节点。

语法说明MATCH (n:Person) 匹配所有带有 Person 标签的节点,RETURN n 返回匹配到的节点。

使用场景:适用于需要查看特定类型实体的情况,如查看所有用户、所有产品等。

注意事项:对于大型数据库,建议添加 LIMIT 限制返回结果数量。

cypher
MATCH (n:Person) RETURN n;

查询特定属性的节点

功能描述:查询具有特定属性值的节点,如查询名为 Alice 的 Person 节点。

语法说明MATCH (n:Person {name: 'Alice'}) 匹配 name 属性为 'Alice' 的 Person 节点,RETURN n 返回匹配到的节点。

使用场景:适用于根据具体属性值查找特定实体的情况,如根据用户名查找用户、根据 ID 查找订单等。

注意事项:建议为经常用于查询的属性创建索引,以提高查询性能。

cypher
MATCH (n:Person {name: 'Alice'}) RETURN n;

查询节点和关系

功能描述:查询节点之间的关系,返回节点、关系和相关联的节点。

语法说明MATCH (n:Person)-[r:FRIEND]->(m:Person) 匹配 Person 节点之间的 FRIEND 关系,RETURN n, r, m 返回起始节点、关系和结束节点。

使用场景:适用于查看实体之间的关联关系,如查看用户的朋友、产品的购买者等。

注意事项:关系方向(->)表示查询的是从 n 到 m 的 FRIEND 关系。

cypher
MATCH (n:Person)-[r:FRIEND]->(m:Person) RETURN n, r, m;

查询特定类型的关系

功能描述:查询多种类型的关系,如同时查询 FRIEND 和 COLLEAGUE 关系。

语法说明MATCH (n:Person)-[r:FRIEND|COLLEAGUE]->(m:Person) 匹配 Person 节点之间的 FRIEND 或 COLLEAGUE 关系,RETURN n, r, m 返回相关节点和关系。

使用场景:适用于需要查看实体之间多种关联关系的情况,如查看用户的朋友和同事。

注意事项:关系类型之间使用 | 分隔,表示逻辑或关系。

cypher
MATCH (n:Person)-[r:FRIEND|COLLEAGUE]->(m:Person) RETURN n, r, m;

高级查询

带条件的查询

功能描述:根据特定条件过滤查询结果,如查询年龄大于 30 岁的人员。

语法说明MATCH (n:Person) 匹配 Person 节点,WHERE n.age > 30 过滤年龄大于 30 的节点,RETURN n.name, n.age 返回姓名和年龄属性。

使用场景:适用于需要根据属性值进行过滤的查询,如查询特定年龄段的用户、特定地区的产品等。

注意事项:WHERE 子句中的属性如果经常用于查询,建议创建索引以提高性能。

cypher
MATCH (n:Person) WHERE n.age > 30 RETURN n.name, n.age;

带排序的查询

功能描述:对查询结果进行排序,如按年龄降序排列人员信息。

语法说明MATCH (n:Person) 匹配 Person 节点,RETURN n.name, n.age 返回姓名和年龄,ORDER BY n.age DESC 按年龄降序排序。

使用场景:适用于需要对结果进行排序展示的情况,如按销售额排序产品、按注册时间排序用户等。

注意事项:ORDER BY 子句会增加查询开销,对于大型结果集,建议结合 LIMIT 使用。

cypher
MATCH (n:Person) RETURN n.name, n.age ORDER BY n.age DESC;

带分页的查询

功能描述:对查询结果进行分页处理,如跳过前 10 条记录,返回接下来的 5 条记录。

语法说明MATCH (n:Person) 匹配 Person 节点,ORDER BY n.age 按年龄排序,SKIP 10 跳过前 10 条,LIMIT 5 返回 5 条记录。

使用场景:适用于 Web 应用中的分页展示,如每页显示 10 条记录,用户可以翻页查看。

注意事项:SKIP 和 LIMIT 结合使用可以实现高效分页,但对于非常大的数据集,建议使用更高效的分页策略。

cypher
MATCH (n:Person) RETURN n.name, n.age ORDER BY n.age SKIP 10 LIMIT 5;

聚合查询

功能描述:对查询结果进行聚合计算,如计数、平均值、最大值、最小值等。

语法说明

  • COUNT(n) 统计节点数量
  • AVG(n.age) 计算年龄平均值
  • MAX(n.age)MIN(n.age) 计算最大和最小年龄

使用场景:适用于数据分析和报表生成,如统计用户数量、计算平均订单金额、查找最高销售额等。

注意事项:聚合函数会对结果集进行计算,对于大型数据集可能会有性能影响。

cypher
MATCH (n:Person) RETURN COUNT(n) AS totalPersons;
MATCH (n:Person) RETURN AVG(n.age) AS averageAge;
MATCH (n:Person) RETURN MAX(n.age) AS maxAge, MIN(n.age) AS minAge;

分组查询

功能描述:根据特定属性或关系进行分组,并对每组进行聚合计算,如统计每个城市的人口数量。

语法说明MATCH (n:Person)-[:LIVES_IN]->(c:City) 匹配居住在城市中的人员,RETURN c.name, COUNT(n) AS population 按城市分组统计人口,ORDER BY population DESC 按人口降序排序。

使用场景:适用于需要按类别进行数据分析的情况,如按地区分组统计销售数据、按产品类型分组统计库存等。

注意事项:分组查询通常与聚合函数结合使用,ORDER BY 可以对分组结果进行排序。

cypher
MATCH (n:Person)-[:LIVES_IN]->(c:City) RETURN c.name, COUNT(n) AS population ORDER BY population DESC;

路径查询

最短路径

功能描述:查找两个节点之间的最短路径,如查找 Alice 和 Bob 之间的最短社交关系路径。

语法说明MATCH shortestPath((a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Bob'})) 查找 Alice 和 Bob 之间的最短路径,RETURN path 返回完整路径。

使用场景:适用于社交网络分析、物流路径规划、知识图谱推理等场景,如查找用户之间的最短连接、商品之间的关联路径等。

注意事项:shortestPath 函数会优化查询性能,避免返回过多路径,对于大型图数据库非常有用。

cypher
MATCH shortestPath((a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Bob'})) RETURN path;

指定最大深度的路径

功能描述:查找指定深度范围内的所有路径,如查找 Alice 1-3 度范围内的所有社交关系。

语法说明MATCH (a:Person {name: 'Alice'})-[*1..3]-(b:Person) 查找 Alice 1-3 度范围内的 Person 节点,RETURN a, b 返回相关节点。

使用场景:适用于需要限制路径深度的查询,如社交网络中的几度人脉查询、推荐系统中的关联推荐等。

注意事项:路径深度(*1..3)中的数字表示最小和最大深度,过深的路径查询会导致性能问题,建议根据实际需求设置合理的深度范围。

cypher
MATCH (a:Person {name: 'Alice'})-[*1..3]-(b:Person) RETURN a, b;

所有路径

功能描述:查找两个节点之间的所有路径,如查找 Alice 和 Bob 之间的所有可能连接路径。

语法说明MATCH (a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Bob'}) 查找 Alice 和 Bob 之间的所有路径,RETURN path 返回完整路径。

使用场景:适用于需要分析所有可能路径的场景,如网络拓扑分析、安全漏洞评估等。

注意事项:查询所有路径可能返回大量结果,甚至导致无限循环,建议仅在小型图数据库或特定场景下使用,并考虑添加路径长度限制。

cypher
MATCH (a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Bob'}) RETURN path;

数据修改

创建节点

cypher
CREATE (n:Person {name: 'Charlie', age: 25, city: 'New York'});

创建关系

cypher
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Charlie'}) CREATE (a)-[r:FRIEND {since: 2023}]->(b);

更新属性

cypher
MATCH (n:Person {name: 'Alice'}) SET n.age = 31, n.city = 'London' RETURN n;

删除属性

cypher
MATCH (n:Person {name: 'Alice'}) REMOVE n.city RETURN n;

删除关系

cypher
MATCH (a:Person {name: 'Alice'})-[r:FRIEND]->(b:Person {name: 'Bob'}) DELETE r;

删除节点

cypher
MATCH (n:Person {name: 'Charlie'}) DELETE n;

删除节点及其所有关系

cypher
MATCH (n:Person {name: 'Charlie'}) DETACH DELETE n;

索引和约束

创建索引

cypher
CREATE INDEX FOR (n:Person) ON (n.name);
CREATE INDEX FOR (n:Person) ON (n.name, n.age);

创建全文索引

cypher
CREATE FULLTEXT INDEX personName FOR (n:Person) ON EACH [n.name, n.bio];

创建唯一约束

cypher
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.email IS UNIQUE;

创建节点存在约束

cypher
CREATE CONSTRAINT FOR (n:Person) REQUIRE n.name IS NOT NULL;

查看索引和约束

cypher
CALL db.indexes();
CALL db.constraints();

事务管理

开始事务

cypher
BEGIN;
MATCH (a:Person {name: 'Alice'}) SET a.age = a.age + 1;
MATCH (b:Person {name: 'Bob'}) SET b.age = b.age + 1;
COMMIT;

回滚事务

cypher
BEGIN;
MATCH (a:Person {name: 'Alice'}) SET a.age = a.age + 1;
ROLLBACK;

系统查询

查看数据库版本

cypher
CALL dbms.components() YIELD name, version RETURN name, version;

查看数据库状态

cypher
CALL dbms.health.check();

查看当前用户

cypher
CALL dbms.security.showCurrentUser();

查看所有用户

cypher
CALL dbms.security.listUsers();

查看所有角色

cypher
CALL dbms.security.listRoles();

性能优化查询

查看查询执行计划

cypher
EXPLAIN MATCH (n:Person)-[:FRIEND]->(m:Person) WHERE n.age > 30 RETURN n, m;

分析查询执行计划

cypher
PROFILE MATCH (n:Person)-[:FRIEND]->(m:Person) WHERE n.age > 30 RETURN n, m;

查看慢查询

cypher
CALL dbms.listQueries();
CALL dbms.listTx();

常见查询模式

好友推荐

cypher
MATCH (a:Person {name: 'Alice'})-[:FRIEND]->(b:Person)-[:FRIEND]->(c:Person) WHERE NOT (a)-[:FRIEND]->(c) RETURN c.name, COUNT(*) AS commonFriends ORDER BY commonFriends DESC;

兴趣图谱

cypher
MATCH (a:Person {name: 'Alice'})-[:LIKES]->(t:Topic)<-[:LIKES]-(b:Person) RETURN b.name, COUNT(t) AS commonInterests ORDER BY commonInterests DESC;

社交影响力

cypher
MATCH (a:Person)-[:FRIEND*1..2]->(b:Person) RETURN a.name, COUNT(DISTINCT b) AS influence ORDER BY influence DESC;

路径分析

cypher
MATCH (start:City {name: 'New York'})-[r:CONNECTED_TO*]->(end:City {name: 'Los Angeles'}) RETURN path, REDUCE(distance = 0, rel IN relationships(path) | distance + rel.distance) AS totalDistance ORDER BY totalDistance ASC LIMIT 5;

导入导出数据

导出数据到 CSV

cypher
MATCH (n:Person) RETURN n.name, n.age, n.city ORDER BY n.name
INTO CSV "file:///persons.csv";

从 CSV 导入数据

cypher
LOAD CSV WITH HEADERS FROM "file:///persons.csv" AS row
CREATE (n:Person {name: row.name, age: toInteger(row.age), city: row.city});

导入带关系的数据

cypher
LOAD CSV WITH HEADERS FROM "file:///relationships.csv" AS row
MATCH (a:Person {name: row.from}), (b:Person {name: row.to})
CREATE (a)-[r:FRIEND {since: toInteger(row.since)}]->(b);

Cypher 查询最佳实践

  1. 使用参数化查询

    cypher
    // 推荐
    MATCH (n:Person {name: $name}) RETURN n;
    
    // 不推荐
    MATCH (n:Person {name: 'Alice'}) RETURN n;
  2. 限制结果集大小

    cypher
    MATCH (n:Person) RETURN n LIMIT 100;
  3. 使用索引

    • 为经常查询的属性创建索引
    • 避免在索引属性上使用函数
  4. 优化路径查询

    • 限制路径的最大深度
    • 使用 shortestPath 替代全路径查询
  5. 避免笛卡尔积

    cypher
    // 避免
    MATCH (a:Person), (b:Person) WHERE a.city = b.city RETURN a, b;
    
    // 推荐
    MATCH (a:Person)-[:LIVES_IN]->(c:City)<-[:LIVES_IN]-(b:Person) RETURN a, b;

常见问题(FAQ)

Q1: 如何优化慢查询?

A1: 优化慢查询的方法包括:

  • 使用 PROFILEEXPLAIN 分析执行计划
  • 为查询中使用的属性创建索引
  • 限制结果集大小和路径深度
  • 避免在查询中使用复杂函数

Q2: 如何处理大型结果集?

A2: 处理大型结果集的方法包括:

  • 使用 LIMITSKIP 进行分页
  • 只返回必要的属性,而不是整个节点
  • 使用批量处理

Q3: 如何删除大量数据?

A3: 删除大量数据时,建议使用批量删除:

cypher
MATCH (n:OldData) WITH n LIMIT 1000 DETACH DELETE n;

Q4: 如何检查索引是否被使用?

A4: 使用 PROFILE 命令查看执行计划,如果索引被使用,会显示 "NodeIndexSeek" 操作。

Q5: 如何在 Cypher 中使用正则表达式?

A5: 可以使用 =~ 操作符进行正则表达式匹配:

cypher
MATCH (n:Person) WHERE n.name =~ 'A.*' RETURN n;