当前位置: 首页 > news >正文

第4章:Cypher查询语言基础

Cypher是Neo4j的声明式图查询语言,专为处理图数据而设计。它允许用户以直观、高效的方式查询和修改图数据库中的数据。本章将介绍Cypher的基本概念和语法,帮助读者掌握使用Cypher进行基础图数据操作的能力。

4.1 Cypher语言概述

Cypher是Neo4j的主要查询语言,其设计理念是让图查询变得简单直观,即使对于没有编程背景的用户也能快速上手。了解Cypher的设计理念和基本语法结构,是掌握这门语言的第一步。

Cypher的设计理念

Cypher 的设计融合了 SQL、SPARQL 和正则表达式等多种语言和概念,其核心理念体现在声明式查询、模式匹配、可读性和灵活性等方面。首先,Cypher 是一种声明式语言,用户只需描述“想要什么”,而无需关心“如何获取”,这让查询更专注于业务需求而非实现细节。其次,Cypher 以模式匹配为核心,用户通过描述节点和关系的结构,Neo4j 引擎自动查找匹配的子图。Cypher 独特的 ASCII 艺术风格语法,使节点和关系的结构在查询语句中直观可见,提升了可读性。其语法接近自然语言,即使复杂查询也能简洁表达,便于理解和维护。此外,Cypher 支持通过组合简单模式构建复杂查询,实现查询的模块化和重用。灵活的查询能力涵盖从精确匹配到路径分析和聚合操作等多种场景。这些设计理念共同造就了 Cypher 强大且易用的特性,适用于各种图数据检索与分析需求。

Cypher与SQL的对比

对于熟悉SQL的用户,了解Cypher与SQL的异同有助于快速掌握这门新语言。

Cypher和SQL都是声明式查询语言,用户只需描述“想要什么”,而无需关心“如何获取”。两者都采用类似的子句结构,例如Cypher的MATCH与SQL的SELECT,以及共同的WHEREORDER BY等子句。此外,它们都支持聚合函数和分组操作,能够对数据进行统计和汇总。无论是Cypher还是SQL,都具备事务支持和数据修改语句,能够保证数据操作的完整性和一致性。

Cypher与SQL的主要区别体现在数据模型、连接方式、关系查询、结果形式和语法风格等方面。首先,SQL采用表格模型,数据以行和列的形式组织,而Cypher则基于图模型,数据以节点、关系和属性的方式存储。其次,在连接操作上,SQL通过JOIN语句实现表之间的关联,而Cypher则通过模式匹配和路径表达式直接描述节点之间的连接。对于复杂关系的查询,SQL需要多个JOIN操作,随着关系层级的增加,查询语句会变得更加复杂;而Cypher可以用简洁的路径表达式(如()-[:KNOWS*1..3]->())直接表示和查询任意深度的关系。查询结果方面,SQL通常返回表格数据(行和列),而Cypher不仅可以返回表格,还能返回路径或子图,更适合图结构的数据分析。最后,语法风格上,SQL以英语关键词和表达式为主,Cypher则结合了英语关键词和ASCII艺术风格的图模式,使查询结构更加直观和易读。

以下是一个简单的对比示例,展示了如何使用Cypher和SQL查询图数据。

查找名为"John"的用户的朋友:

SQL(假设有Users表和Friendships表):

SELECT f.name
FROM Users u
JOIN Friendships fs ON u.id = fs.user_id
JOIN Users f ON fs.friend_id = f.id
WHERE u.name = 'John';

Cypher:

MATCH (u:User {name: 'John'})-[:FRIENDS_WITH]->(f:User)
RETURN f.name;

查找朋友的朋友:

SQL:

SELECT ff.name
FROM Users u
JOIN Friendships fs1 ON u.id = fs1.user_id
JOIN Users f ON fs1.friend_id = f.id
JOIN Friendships fs2 ON f.id = fs2.user_id
JOIN Users ff ON fs2.friend_id = ff.id
WHERE u.name = 'John'
AND ff.id <> u.id;  -- 排除自己

Cypher:

MATCH (u:User {name: 'John'})-[:FRIENDS_WITH]->(f:User)-[:FRIENDS_WITH]->(ff:User)
WHERE u <> ff  -- 排除自己
RETURN ff.name;

这种对比清晰地展示了Cypher在处理关联数据时的简洁性和直观性。随着关系复杂度的增加,这种优势会变得更加明显。

Cypher的语法结构

Cypher查询语句由多个子句组成,每个子句负责查询的不同方面。理解这些基本子句及其组合方式是掌握Cypher的基础。

主要子句及其功能

  1. MATCH:指定要在图中查找的模式。这是大多数Cypher查询的起点。

    MATCH (p:Person)-[:WORKS_FOR]->(c:Company)
    
  2. WHERE:添加过滤条件,限制匹配结果。

    WHERE p.age > 30 AND c.name = 'Neo4j'
    
  3. RETURN:指定查询结果中应包含哪些数据。

    RETURN p.name, p.age, c.name
    
  4. ORDER BY:对结果进行排序。

    ORDER BY p.age DESC
    
  5. SKIP/LIMIT:分页或限制结果数量。

    SKIP 10 LIMIT 5
    
  6. CREATE:创建新的节点或关系。

    CREATE (p:Person {name: 'Alice', age: 30})
    
  7. MERGE:查找现有模式,如果不存在则创建。

    MERGE (p:Person {name: 'Bob'})
    
  8. SET:设置或更新属性。

    SET p.age = 31
    
  9. DELETE/DETACH DELETE:删除节点或关系。

    DETACH DELETE p
    
  10. WITH:将一个查询部分的结果传递给下一个部分,允许查询链接。

    MATCH (p:Person)
    WITH p, size((p)-[:KNOWS]->()) AS friendCount
    WHERE friendCount > 5
    RETURN p.name, friendCount
    

Cypher语句的基本结构通常遵循这样的模式:

  1. 使用MATCH找到图中的模式
  2. 使用WHERE应用过滤条件
  3. 使用RETURN指定输出
  4. 可选地使用ORDER BYSKIPLIMIT等修饰结果

更复杂的查询可能包括:

  • 多个MATCH子句
  • 使用WITH连接的多个查询部分
  • 子查询和复合查询
  • 聚合和分组操作

节点和关系的表示

  • 节点用圆括号表示:()
  • 可以为节点指定变量名:(p)
  • 可以为节点指定标签:(p:Person)
  • 可以为节点指定属性:(p:Person {name: 'Alice'})
  • 关系用方括号表示,并用箭头指示方向:-[:KNOWS]->
  • 可以为关系指定变量名:-[r:KNOWS]->
  • 可以为关系指定属性:-[r:KNOWS {since: 2020}]->
  • 可以指定关系的方向,或者不指定方向(双向):-[:KNOWS]->, <-[:KNOWS]-, -[:KNOWS]-

路径变量
可以为整个路径指定一个变量,以便后续引用:

MATCH p = (a:Person)-[:KNOWS]->(b:Person)
RETURN p

理解这些基本语法元素及其组合方式,是掌握Cypher的关键。随着经验的积累,您将能够编写越来越复杂和强大的查询。

4.2 基本查询操作

掌握基本的查询操作是使用Cypher的第一步。本节将介绍如何使用MATCH、WHERE、RETURN等子句进行基本的数据检索。

MATCH与WHERE子句

MATCH子句是Cypher查询的核心,用于指定要在图中查找的模式。WHERE子句则用于添加过滤条件,进一步限定匹配结果。

基本的MATCH用法

  1. 匹配特定标签的节点

    MATCH (p:Person)
    RETURN p
    

    这将返回所有带有Person标签的节点。

  2. 匹配多个标签

    MATCH (p:Person:Employee)
    RETURN p
    

    这将返回同时带有PersonEmployee标签的节点。

  3. 匹配特定属性的节点

    MATCH (p:Person {name: 'Alice'})
    RETURN p
    

    这将返回标签为Personname属性值为’Alice’的节点。

  4. 匹配关系

    MATCH (p:Person)-[:KNOWS]->(friend)
    RETURN p, friend
    

    这将返回所有Person节点及其通过KNOWS关系连接的朋友节点。

  5. 匹配多跳关系

    MATCH (p:Person)-[:KNOWS*1..3]->(friend)
    RETURN p, friend
    

    这将返回与Person节点之间有1到3跳KNOWS关系的朋友节点。

WHERE子句的使用

  1. 基本比较

    MATCH (p:Person)
    WHERE p.age > 30
    RETURN p
    

    返回年龄大于30的所有Person节点。

  2. 多条件过滤

    MATCH (p:Person)
    WHERE p.age > 30 AND p.city = 'London'
    RETURN p
    

    返回年龄大于30且城市为London的所有Person节点。

  3. 字符串操作

    MATCH (p:Person)
    WHERE p.name STARTS WITH 'A'
    RETURN p
    

    返回名字以’A’开头的所有Person节点。

  4. 正则表达式

    MATCH (p:Person)
    WHERE p.email =~ '.*@gmail\\.com'
    RETURN p
    

    返回Gmail邮箱的所有Person节点。

  5. 列表操作

    MATCH (p:Person)
    WHERE 'Java' IN p.skills
    RETURN p
    

    返回技能列表中包含’Java’的所有Person节点。

  6. 存在性检查

    MATCH (p:Person)
    WHERE exists(p.phone)
    RETURN p
    

    返回有phone属性的所有Person节点。

  7. 路径过滤

    MATCH (p:Person)-[r:RATED]->(m:Movie)
    WHERE r.score > 4
    RETURN p, m
    

    返回评分高于4的所有人-电影对。

MATCH和WHERE的组合使用允许构建复杂的查询模式和过滤条件,是Cypher查询的基础。

RETURN与ORDER BY子句

RETURN子句指定查询结果中应包含哪些数据,而ORDER BY子句则用于对结果进行排序。

RETURN子句的用法

  1. 返回整个节点或关系

    MATCH (p:Person)
    RETURN p
    

    返回完整的Person节点,包括所有属性。

  2. 返回特定属性

    MATCH (p:Person)
    RETURN p.name, p.age
    

    只返回Person节点的nameage属性。

  3. 使用别名

    MATCH (p:Person)
    RETURN p.name AS Name, p.age AS Age
    

    为返回的属性指定别名,使结果更易读。

  4. 返回计算结果

    MATCH (p:Person)
    RETURN p.name, p.birthYear, 2023 - p.birthYear AS Age
    

    返回计算得出的年龄。

  5. 返回去重结果

    MATCH (p:Person)-[:LIVES_IN]->(c:City)
    RETURN DISTINCT c.name
    

    返回不重复的城市名称。

  6. 返回聚合结果

    MATCH (p:Person)
    RETURN count(p) AS PersonCount, avg(p.age) AS AvgAge
    

    返回人数统计和平均年龄。

ORDER BY子句的用法

  1. 基本排序

    MATCH (p:Person)
    RETURN p.name, p.age
    ORDER BY p.age
    

    按年龄升序排列结果。

  2. 指定排序方向

    MATCH (p:Person)
    RETURN p.name, p.age
    ORDER BY p.age DESC
    

    按年龄降序排列结果。

  3. 多字段排序

    MATCH (p:Person)
    RETURN p.name, p.age, p.city
    ORDER BY p.city, p.age DESC
    

    先按城市升序排列,城市相同的再按年龄降序排列。

  4. 使用表达式排序

    MATCH (p:Person)-[:KNOWS]->(friend)
    RETURN p.name, count(friend) AS FriendCount
    ORDER BY FriendCount DESC
    

    按朋友数量降序排列。

  5. 使用别名排序

    MATCH (p:Person)
    RETURN p.name AS Name, p.age AS Age
    ORDER BY Age
    

    使用返回结果的别名进行排序。

RETURNORDER BY子句的灵活使用,可以帮助您获取所需的数据并以合适的方式呈现。

LIMIT与SKIP子句

LIMITSKIP子句用于控制返回结果的数量和起始位置,常用于分页查询。

LIMIT子句限制返回的结果数量:

MATCH (p:Person)
RETURN p.name, p.age
LIMIT 10

这将只返回前10个结果。

SKIP子句跳过指定数量的结果:

MATCH (p:Person)
RETURN p.name, p.age
SKIP 10

这将跳过前10个结果,从第11个开始返回。

组合使用实现分页:

MATCH (p:Person)
RETURN p.name, p.age
ORDER BY p.name
SKIP 20 LIMIT 10

这将返回按名字排序后的第21到第30个结果,相当于第3页(假设每页10条)。

注意事项

  • 使用SKIPLIMIT进行分页时,应始终配合ORDER BY使用,以确保分页结果的一致性。
  • 对于大数据集,大的SKIP值可能导致性能问题,因为Neo4j需要先找到所有匹配的结果,然后跳过指定数量。在这种情况下,可以考虑使用其他分页策略,如基于上一页最后一个结果的属性值进行过滤。

基础查询模式

掌握一些常见的查询模式,可以帮助您更有效地使用Cypher。以下是一些基础查询模式:

  1. 查找与特定节点相关的节点

    MATCH (p:Person {name: 'Alice'})-[:KNOWS]->(friend)
    RETURN friend.name
    

    查找Alice认识的所有人。

  2. 查找两个节点之间的关系

    MATCH (p1:Person {name: 'Alice'})-[r]-(p2:Person {name: 'Bob'})
    RETURN type(r), r
    

    查找Alice和Bob之间的所有关系。

  3. 查找满足特定条件的路径

    MATCH path = (start:Person {name: 'Alice'})-[:KNOWS*1..3]-(end:Person {name: 'Charlie'})
    RETURN path
    

    查找Alice和Charlie之间最多3跳的"认识"路径。

  4. 查找没有特定关系的节点

    MATCH (p:Person)
    WHERE NOT (p)-[:LIVES_IN]->()
    RETURN p.name
    

    查找没有指定居住地的人。

  5. 查找具有最多关系的节点

    MATCH (p:Person)-[:KNOWS]->(friend)
    RETURN p.name, count(friend) AS FriendCount
    ORDER BY FriendCount DESC
    LIMIT 5
    

    查找朋友最多的5个人。

  6. 查找共同关系

    MATCH (p1:Person {name: 'Alice'})-[:KNOWS]->(common)<-[:KNOWS]-(p2:Person {name: 'Bob'})
    RETURN common.name
    

    查找Alice和Bob共同认识的人。

  7. 条件路径查询

    MATCH (p:Person {name: 'Alice'})-[:KNOWS]->(friend)
    WHERE friend.age > 30
    RETURN friend.name, friend.age
    

    查找Alice认识的年龄大于30岁的朋友。

  8. 组合多个MATCH子句

    MATCH (p:Person {name: 'Alice'})
    MATCH (p)-[:LIVES_IN]->(city)
    MATCH (other:Person)-[:LIVES_IN]->(city)
    WHERE other <> p
    RETURN other.name AS Neighbor, city.name AS City
    

    查找与Alice住在同一城市的其他人。

这些基础查询模式可以根据具体需求进行调整和组合,构建更复杂的查询。随着对Cypher的深入理解,您将能够设计出更高效、更精确的查询来满足各种业务需求。

4.3 创建与修改操作

除了查询数据,Cypher还提供了强大的数据创建和修改功能。本节将介绍如何使用CREATE、MERGE、SET等命令来添加和更新图数据。

CREATE与MERGE命令

CREATE命令用于在图中创建新的节点和关系,而MERGE命令则结合了查找和创建功能,只在不存在时才创建新的元素。

CREATE命令的用法

  1. 创建单个节点

    CREATE (p:Person {name: 'Alice', age: 30})
    

    创建一个带有Person标签和两个属性的节点。

  2. 创建多个节点

    CREATE (p1:Person {name: 'Alice', age: 30}),(p2:Person {name: 'Bob', age: 35})
    

    一次创建多个节点。

  3. 创建节点和关系

    CREATE (p1:Person {name: 'Alice'})-[:KNOWS {since: 2020}]->(p2:Person {name: 'Bob'})
    

    创建两个节点及它们之间的关系。

  4. 创建关系(节点已存在)

    MATCH (p1:Person {name: 'Alice'}), (p2:Person {name: 'Bob'})
    CREATE (p1)-[:KNOWS {since: 2020}]->(p2)
    

    在已存在的节点之间创建关系。

MERGE命令的用法

  1. 合并节点

    MERGE (p:Person {name: 'Alice'})
    ON CREATE SET p.created = timestamp()
    ON MATCH SET p.lastSeen = timestamp()
    

    如果不存在名为’Alice’的Person节点,则创建一个并设置created属性;如果已存在,则更新lastSeen属性。

  2. 合并关系

    MATCH (p1:Person {name: 'Alice'}), (p2:Person {name: 'Bob'})
    MERGE (p1)-[r:KNOWS]->(p2)
    ON CREATE SET r.since = 2020
    

    如果Alice和Bob之间不存在KNOWS关系,则创建一个并设置since属性。

  3. 合并完整路径

    MERGE (p1:Person {name: 'Alice'})-[r:KNOWS]->(p2:Person {name: 'Bob'})
    

    这将确保整个路径存在,如果任何部分(节点或关系)不存在,则创建它。

CREATE与MERGE的区别

  • CREATE总是创建新的节点或关系,即使完全相同的已经存在。
  • MERGE首先尝试查找匹配的模式,只有在不存在时才创建新的元素。
  • 使用MERGE时,可以使用ON CREATEON MATCH子句分别处理创建和匹配的情况。

使用建议

  • 当确定要创建新元素且不关心重复时,使用CREATE
  • 当需要确保唯一性或实现"查找或创建"逻辑时,使用MERGE
  • 对于大批量数据导入,CREATE通常比MERGE更高效,因为它不需要先查找。

SET与REMOVE命令

SET命令用于添加或更新节点和关系的属性或标签,而REMOVE命令用于删除属性或标签。

SET命令的用法

  1. 设置或更新单个属性

    MATCH (p:Person {name: 'Alice'})
    SET p.age = 31
    

    将Alice的年龄更新为31。

  2. 同时设置多个属性

    MATCH (p:Person {name: 'Alice'})
    SET p.age = 31, p.updated = timestamp()
    

    同时更新多个属性。

  3. 使用属性映射设置多个属性

    MATCH (p:Person {name: 'Alice'})
    SET p += {age: 31, city: 'London', updated: timestamp()}
    

    使用映射一次性设置多个属性。

  4. 添加标签

    MATCH (p:Person {name: 'Alice'})
    SET p:Employee
    

    给节点添加新的标签。

  5. 替换所有属性

    MATCH (p:Person {name: 'Alice'})
    SET p = {name: 'Alice', age: 31, city: 'London'}
    

    这将替换节点的所有现有属性。注意:这会删除未在新映射中指定的任何属性。

REMOVE命令的用法

  1. 删除属性

    MATCH (p:Person {name: 'Alice'})
    REMOVE p.age
    

    删除Alice的年龄属性。

  2. 删除多个属性

    MATCH (p:Person {name: 'Alice'})
    REMOVE p.age, p.city
    

    同时删除多个属性。

  3. 删除标签

    MATCH (p:Person:Temporary {name: 'Alice'})
    REMOVE p:Temporary
    

    删除节点的Temporary标签。

SET与REMOVE的注意事项

  • SET可以添加新属性或覆盖现有属性,但不会删除未提及的属性。
  • 使用SET p = {...}会替换所有现有属性,可能导致数据丢失。
  • REMOVE永久删除属性或标签,无法撤销。
  • 删除节点的最后一个标签不会删除节点本身。
  • 属性值可以设置为null,但这与删除属性不同。设置为null的属性仍然存在,只是值为null

DELETE与DETACH DELETE命令

DELETE命令用于删除节点和关系,而DETACH DELETE命令用于删除节点及其所有关系。

DELETE命令的用法

  1. 删除关系

    MATCH (p1:Person {name: 'Alice'})-[r:KNOWS]->(p2:Person {name: 'Bob'})
    DELETE r
    

    删除Alice和Bob之间的KNOWS关系。

  2. 删除没有关系的节点

    MATCH (p:Person {name: 'Charlie'})
    WHERE NOT (p)--()  // 确保节点没有关系
    DELETE p
    

    删除没有任何关系的Charlie节点。

DETACH DELETE命令的用法

  1. 删除节点及其所有关系

    MATCH (p:Person {name: 'Alice'})
    DETACH DELETE p
    

    删除Alice节点及其所有入站和出站关系。

  2. 删除多个节点及其关系

    MATCH (p:Person)
    WHERE p.inactive = true
    DETACH DELETE p
    

    删除所有标记为非活跃的人及其关系。

DELETE与DETACH DELETE的注意事项

  • 尝试删除仍有关系的节点(不使用DETACH)会导致错误。
  • DETACH DELETE是一个强大的操作,会删除节点的所有关系,使用时需谨慎。
  • 删除操作是永久性的,无法撤销。在生产环境中执行删除操作前,建议先进行备份或使用测试数据库。
  • 可以在一个事务中组合多个操作,例如先创建新节点,然后删除旧节点。

基础修改模式

以下是一些常见的数据修改模式,展示了如何组合使用上述命令来完成常见任务:

  1. 创建唯一节点

    MERGE (p:Person {email: 'alice@example.com'})
    ON CREATE SET p.name = 'Alice', p.created = timestamp()
    

    确保每个电子邮件只对应一个Person节点。

  2. 添加关系(如果不存在)

    MATCH (p1:Person {name: 'Alice'}), (p2:Person {name: 'Bob'})
    MERGE (p1)-[r:KNOWS]->(p2)
    ON CREATE SET r.since = date()
    

    确保Alice和Bob之间有一个KNOWS关系。

  3. 更新或创建节点和关系

    MERGE (p:Person {email: 'alice@example.com'})
    ON CREATE SET p.name = 'Alice', p.created = timestamp()
    ON MATCH SET p.lastSeen = timestamp()
    WITH p
    MATCH (c:Company {name: 'Neo4j'})
    MERGE (p)-[r:WORKS_FOR]->(c)
    ON CREATE SET r.since = date()
    

    确保用户存在并与公司有工作关系。

  4. 条件更新

    MATCH (p:Person {name: 'Alice'})
    SET p.age = CASE WHEN p.age IS NULL THEN 30 ELSE p.age + 1 END
    

    如果年龄未设置,则设为30;否则增加1。

  5. 批量更新

    MATCH (p:Person)
    WHERE p.city = 'New York'
    SET p.region = 'East Coast'
    

    为所有纽约的人设置区域属性。

  6. 替换节点

    MATCH (old:Person {name: 'Alice', outdated: true})
    CREATE (new:Person {name: 'Alice', updated: true})
    WITH old, new
    MATCH (old)-[r]->(other)
    CREATE (new)-[r2:KNOWS]->(other)
    SET r2 = properties(r)
    WITH old, new
    MATCH (other)-[r]->(old)
    CREATE (other)-[r2:KNOWS]->(new)
    SET r2 = properties(r)
    WITH old
    DETACH DELETE old
    

    创建节点的新版本,复制所有关系,然后删除旧节点。

  7. 有条件地删除数据

    MATCH (p:Person)-[r:VISITED]->(c:City)
    WHERE r.lastVisit < date('2020-01-01')
    DELETE r
    

    删除2020年之前的访问记录。

这些基础修改模式展示了Cypher在数据操作方面的灵活性和表达能力。通过组合不同的命令和子句,可以实现各种复杂的数据修改需求。

4.4 基础查询模式

在实际应用中,某些查询模式会反复出现。掌握这些常见的查询模式,可以帮助您更有效地使用Cypher解决实际问题。

节点查询模式

节点查询是最基本的查询类型,涉及查找和过滤特定类型的节点。

  1. 基于标签查询

    MATCH (p:Person)
    RETURN p
    

    查找所有Person节点。

  2. 基于属性查询

    MATCH (p:Person {name: 'Alice'})
    RETURN p
    

    查找名为’Alice’的Person节点。

  3. 使用WHERE子句的复杂过滤

    MATCH (p:Person)
    WHERE p.age > 30 AND p.city = 'London'
    RETURN p
    

    查找年龄大于30且住在伦敦的人。

  4. 模糊查询

    MATCH (p:Person)
    WHERE p.name CONTAINS 'Al' OR p.name STARTS WITH 'B'
    RETURN p
    

    查找名字包含’Al’或以’B’开头的人。

  5. 正则表达式查询

    MATCH (p:Person)
    WHERE p.email =~ '.*@gmail\\.com'
    RETURN p
    

    查找使用Gmail的人。

  6. 空值处理

    MATCH (p:Person)
    WHERE p.age IS NULL
    RETURN p
    

    查找未设置年龄的人。

  7. 列表属性查询

    MATCH (p:Person)
    WHERE 'Java' IN p.skills
    RETURN p
    

    查找技能包含’Java’的人。

  8. 计算属性查询

    MATCH (p:Person)
    WHERE size(p.name) > 5
    RETURN p
    

    查找名字长度大于5的人。

关系查询模式

关系查询涉及查找节点之间的连接和路径。

  1. 基本关系查询

    MATCH (p:Person)-[:KNOWS]->(friend)
    RETURN p.name, friend.name
    

    查找所有人及其认识的朋友。

  2. 特定关系查询

    MATCH (p:Person {name: 'Alice'})-[:KNOWS]->(friend)
    RETURN friend.name
    

    查找Alice认识的所有人。

  3. 关系属性过滤

    MATCH (p:Person)-[r:KNOWS]->(friend)
    WHERE r.since > 2018
    RETURN p.name, friend.name, r.since
    

    查找2018年之后建立的朋友关系。

  4. 多重关系查询

    MATCH (p:Person)-[:KNOWS|:WORKS_WITH]->(other)
    RETURN p.name, other.name
    

    查找通过’认识’或’一起工作’关系连接的人。

  5. 关系方向不限

    MATCH (p:Person {name: 'Alice'})-[:KNOWS]-(friend)
    RETURN friend.name
    

    查找与Alice互相认识的人(不考虑关系方向)。

  6. 关系类型动态查询

    MATCH (p:Person {name: 'Alice'})-[r]->(other)
    RETURN type(r), other.name
    

    查找Alice与其他节点之间的所有关系类型。

  7. 关系计数

    MATCH (p:Person)
    RETURN p.name, size((p)-[:KNOWS]->()) AS FriendCount
    

    统计每个人的朋友数量。

路径查询模式

路径查询涉及查找节点之间的连接路径,可能跨越多个关系。

  1. 固定长度路径

    MATCH (p1:Person {name: 'Alice'})-[:KNOWS]->(friend)-[:KNOWS]->(foaf)
    RETURN foaf.name
    

    查找Alice的朋友的朋友。

  2. 可变长度路径

    MATCH (p1:Person {name: 'Alice'})-[:KNOWS*1..3]->(other)
    RETURN other.name
    

    查找与Alice距离1到3跳的所有人。

  3. 最短路径

    MATCH p = shortestPath((p1:Person {name: 'Alice'})-[:KNOWS*]-(p2:Person {name: 'Charlie'}))
    RETURN length(p), [n IN nodes(p) | n.name]
    

    查找Alice和Charlie之间的最短路径。

  4. 所有简单路径

    MATCH p = allShortestPaths((p1:Person {name: 'Alice'})-[:KNOWS*]-(p2:Person {name: 'Charlie'}))
    RETURN p
    

    查找Alice和Charlie之间的所有最短路径。

  5. 带条件的路径查询

    MATCH path = (p1:Person {name: 'Alice'})-[:KNOWS*1..3]->(p2:Person)
    WHERE all(r IN relationships(path) WHERE r.active = true)
    RETURN p2.name
    

    查找通过所有活跃关系连接的人。

  6. 路径不包含特定节点

    MATCH path = (p1:Person {name: 'Alice'})-[:KNOWS*1..3]->(p2:Person {name: 'Charlie'})
    WHERE none(n IN nodes(path) WHERE n.name = 'Bob')
    RETURN path
    

    查找不经过Bob的从Alice到Charlie的路径。

  7. 带权重的路径查询

    MATCH path = (p1:Person {name: 'Alice'})-[:KNOWS*1..3]->(p2:Person)
    RETURN p2.name, reduce(weight = 0, r IN relationships(path) | weight + r.strength) AS TotalStrength
    

    计算路径上所有关系强度的总和。

这些基础查询模式涵盖了大多数常见的图数据查询需求。通过组合和扩展这些模式,可以构建更复杂、更强大的查询来解决各种业务问题。随着对Cypher的深入理解和实践,您将能够设计出更高效、更精确的查询来满足特定需求。

4.5 小结

本章介绍了Cypher的基本语法和查询操作,包括与SQL的对比、基本查询子句、数据创建和修改命令,以及常见的查询模式。通过掌握这些基础知识,您可以开始使用Cypher进行图数据的查询和操作。

相关文章:

  • DNAMAN汉化版免费下载教程---WIN11
  • LeetCode 239. 滑动窗口最大值(单调队列)
  • sql中group by使用场景
  • 项目-- Json-Rpc框架
  • 有没有 MariaDB 5.5.56 对应 MySQL CONNECTION_CONTROL 插件
  • 家政小程序开发——AI+IoT技术融合,打造“智慧家政”新物种
  • Cline核心说明文档
  • 计算机组织原理第五章
  • 【图像处理基石】如何构建一个简单好用的美颜算法?
  • 2007-2023年数字经济上市公司专利申请获得数据
  • [最全总结]城市灾害应急管理系统
  • 【AI系列】BM25 与向量检索
  • JDK21深度解密 Day 15:JDK21实战最佳实践总结
  • 使用柏林噪声生成随机地图
  • C++ 信息学奥赛总复习题答案解析
  • 将单体架构项目拆分成微服务时的两种工程结构
  • DL00335-基于深度学习YOLOv11的煤矸石检测含完整数据集
  • JUC 串讲
  • Ubuntu挂载本地镜像源(像CentOS 一样挂载本地镜像源)
  • 如何判断当前web页面是在钉钉内部打开的?
  • 个人网站可以做淘宝客吗/海淀区seo搜索优化
  • 县城服务网站如何做/百度指数教程
  • b2b免费发布网站大全排名/最近爆发什么病毒感染
  • 怎么建立自己的个人网站/什么是网络营销策略
  • 商丘行业网站建设开发公司/微信营销推广
  • 烟台网站建设方案策划/企业建站模板