无题

无题
mengnankkzhou入门
核心概念
- 节点 (Node): 代表实体,就像关系型数据库中的一行数据。例如:一个人、一部电影、一个公司。节点可以有标签 (Label) 来分类,比如
:Person,:Movie。 - 关系 (Relationship): 代表节点之间的连接,这是图数据库的精髓。例如:
[:ACTED_IN](出演),[:DIRECTED](导演)。关系必须有方向和类型。 - 属性 (Property): 节点和关系都可以有属性,用来存储键值对数据。例如:一个
:Person节点可以有name: 'Keanu Reeves'属性。
语句:
MERGE: 一个非常强大的命令,可以理解为 “匹配或创建”。如果节点/关系已存在,就匹配它;如果不存在,就创建它。常用来避免创建重复数据。WHERE: 过滤条件,用法和 SQL 非常相似。SET: 修改节点或关系的属性。DELETE/DETACH DELETE: 删除节点和关系。DETACH DELETE会在删除节点的同时,删除与它相连的所有关系。可变长度路径: 查询两个节点之间任意长度的路径,例如
(a)-[*2..5]->(b)表示查找 a 和 b 之间长度为 2 到 5 的路径。- 聚合 (Aggregation): 类似于 SQL 的
GROUP BY,例如count(),sum(),avg(),collect()。 WITH: 管道命令。将一个查询的结果,作为下一个查询的输入,构建复杂的查询逻辑。
技巧
高级 Cypher 查询技巧
- 列表推导 (List Comprehension): 类似于 Python,可以快速生成列表。
找到一部电影的所有演员,并返回他们的出生年份列表。
1 | MATCH (p:Person)-[:ACTED_IN]->(m:Movie {title: 'The Matrix'}) |
- 字符串函数:
split(),substring(),toLower(),replace()等。
设人名存的是 “Reeves, Keanu”,我们想把它规范化。
1 | MATCH (p:Person) |
- UNWIND,它可以将一个列表展开成多行数据,方便后续处理。
1 | WITH ['Laurence Fishburne', 'Carrie-Anne Moss', 'Hugo Weaving'] AS actorNames |
- 这个查询会把3个演员名字的列表展开成3行,然后对每一行执行
MERGE操作,非常高效。
OPTIONAL MATCH: 类似 SQL 的 LEFT JOIN
MATCH 必须匹配到完整的模式,否则返回空。而 OPTIONAL MATCH 即使模式的某个部分不存在,也依然会返回结果,缺失的部分用 null 表示。
1 | MATCH (m:Movie) |
5.Case 条件逻辑
根据电影的上映年份,给电影打上“经典”或“现代”的标签
1 | MATCH (m:Movie) |
图建模的构建
核心原则:
将实体建模为节点,将关系建模为关系: 这是最基本的原则。
细化标签: 不要只有一个
:User标签,可以有:User,:Customer,:Admin等,方便查询。关系的方向和类型至关重要:
(a)-[:FRIEND_OF]->(b)和(b)-[:FRIEND_OF]->(a)可能意义不同(比如 Twitter 的关注)。中间节点 (Intermediate Nodes)
: 当一个关系本身需要有很多属性,或者需要被其他节点连接时,可以把它变成一个节点。
- 坏模型:
(Person)-[:PURCHASED {price: 100, date: '...', quantity: 2}]->(Product)。如果购买这个行为还需要关联一个:Store节点,就很难办。 - 好模型:
(Person)-[:MADE_PURCHASE]->(purchase:Order)-[:INCLUDES_PRODUCT]->(Product)。现在,:Order节点可以拥有所有购买相关的属性,并且可以轻松地与:Store节点建立关系。
- 坏模型:
示例:社交网络
- 需求: 用户可以发帖子,可以评论帖子,可以给帖子点赞,用户之间可以互相关注。
- 模型设计:
- 节点:
(:User {userId, name}),(:Post {postId, content, timestamp}) - 关系:
(u:User)-[:POSTED]->(p:Post)(u:User)-[:COMMENTED_ON {text, timestamp}]->(p:Post)(u:User)-[:LIKED]->(p:Post)(u1:User)-[:FOLLOWS]->(u2:User)
- 节点:
比如:
- 查找我关注的人最新发布的帖子:
1 | MATCH (me:User {name: 'Alice'})-[:FOLLOWS]->(friend:User)-[:POSTED]->(post:Post) |
索引
Neo4j 支持多种索引,最常用的是针对节点标签和属性的 RANGE 索引。
1 | CREATE RANGE INDEX person_name_index FOR (p:Person) ON (p.name) |
- 当你执行
MATCH (p:Person {name: 'Tom Hanks'})这样的查询时,Neo4j 会利用这个索引快速定位到节点,而不是扫描所有的:Person节点。这会将查询速度从 O(N) 提升到 O(logN)。 - 何时创建: 在你经常用于
MATCH或WHERE子句中进行查找的属性上创建索引。
EXPLAIN 和 PROFILE
EXPLAIN: 估算查询的执行计划,但不实际执行查询。
PROFILE: 实际执行查询,并返回详细的执行报告,包括每个操作实际命中了多少数据(DB Hits)、耗时多久等。这是性能调优最常用的工具。
查看 PROFILE 的输出,找到 DB Hits 最高的步骤。通常这就是性能瓶颈所在。如果某个 NodeByLabelScan 操作的 DB Hits 很高,就说明你可能需要为那个标签和属性添加一个索引。
六度分隔理论
如果把全世界的每一个人看作一个节点 (Node),人与人之间的认识关系看作一条边 (Edge/Relationship),那么这个理论断言:在这个巨大的人际关系图中,任意两个节点之间的最短路径 (Shortest Path) 的长度平均约为 6。






