导航菜单

  • 1.langchain.intro
  • 2.langchain.chat_models
  • 3.langchain.prompts
  • 4.langchain.example_selectors
  • 5.output_parsers
  • 6.Runnable
  • 7.memory
  • 8.document_loaders
  • 9.text_splitters
  • 10.embeddings
  • 11.tool
  • 12.retrievers
  • 13.optimize
  • 14.项目介绍
  • 15.启动HTTP
  • 16.数据与模型
  • 17.权限管理
  • 18.知识库管理
  • 19.设置
  • 20.文档管理
  • 21.聊天
  • 22.API文档
  • 23.RAG优化
  • 24.索引时优化
  • 25.检索前优化
  • 26.检索后优化
  • 27.系统优化
  • 28.GraphRAG
  • 29.图
  • 30.为什么选择图数据库
  • 31.什么是 Neo4j
  • 32.安装和连接 Neo4j
  • 33.Neo4j核心概念
  • 34.Cypher基础
  • 35.模式匹配
  • 36.数据CRUD操作
  • 37.GraphRAG
  • 38.查询和过滤
  • 39.结果处理和聚合
  • 40.语句组合
  • 41.子查询
  • 42.模式和约束
  • 43.日期时间处理
  • 44.Cypher内置函数
  • 45.Python操作Neo4j
  • 46.neo4j
  • 47.py2neo
  • 48.Streamlit
  • 49.Pandas
  • 50.graphRAG
  • 51.deepdoc
  • 52.deepdoc
  • 53.deepdoc
  • 55.deepdoc
  • 54.deepdoc
  • Pillow
  • 1. 什么是查询过滤
    • 1.1 为什么需要过滤?
    • 1.2 过滤的方式
    • 1.3 前置知识:WHERE子句
  • 2. WHERE子句基础
    • 2.1 WHERE子句的基本语法
    • 2.2 WHERE子句的作用
  • 3. 基本过滤条件
    • 3.1 相等比较
    • 3.2 不等比较
    • 3.3 逻辑操作符(AND, OR, NOT)
  • 4. 范围查询
    • 4.1 前置知识:范围查询
    • 4.2 范围查询的语法
    • 4.3 数值范围查询
    • 4.4 日期范围查询
  • 5. 属性存在性检查
    • 5.1 前置知识:NULL值
    • 5.2 检查属性是否存在
  • 6. 字符串匹配
    • 6.1 前置知识:字符串匹配
    • 6.2 字符串匹配的方式
    • 6.3 基本字符串匹配
    • 6.4 正则表达式匹配(高级)
  • 7. 模式过滤
    • 7.1 前置知识:模式作为条件
    • 7.2 检查关系是否存在
  • 8. 可选匹配(OPTIONAL MATCH)
    • 8.1 前置知识:MATCH vs OPTIONAL MATCH
    • 8.2 为什么需要OPTIONAL MATCH?
    • 8.3 基本用法
  • 9. 复杂模式查询
    • 9.1 多跳关系查询
    • 9.2 查找有共同兴趣的人
  • 10. 小结
    • 10.1 核心概念
    • 10.2 查询优化建议
    • 10.3 最佳实践

1. 什么是查询过滤 #

在实际应用中,我们通常不需要查询图中的所有数据,而是需要根据特定条件筛选出符合要求的数据。这个过程就叫做查询过滤。

1.1 为什么需要过滤? #

想象一下,如果你要在一个包含成千上万人物的社交网络图中查找"所有年龄在25-30岁之间、居住在北京市、喜欢编程的人",你肯定不希望返回所有人的信息,而是只返回符合这些条件的人。这就是过滤的作用。

1.2 过滤的方式 #

在Cypher中,主要有两种方式来实现过滤:

  1. 在MATCH中直接指定条件:适合简单的、单一的过滤条件
  2. 使用WHERE子句:适合复杂的、需要组合多个条件的过滤

1.3 前置知识:WHERE子句 #

WHERE子句是Cypher中用于过滤查询结果的关键字,类似于SQL中的WHERE子句。它的作用是:

  • 在MATCH匹配到数据后,进一步筛选出符合条件的数据
  • 支持多种比较操作符(=, <>, >, <, >=, <=)
  • 支持逻辑操作符(AND, OR, NOT)
  • 支持字符串匹配、范围查询等高级功能

2. WHERE子句基础 #

WHERE子句是Cypher中最重要的过滤工具。它允许你在查询中添加条件,只返回满足这些条件的数据。

2.1 WHERE子句的基本语法 #

WHERE子句通常紧跟在MATCH子句之后,在RETURN子句之前:

MATCH (节点)
WHERE 条件
RETURN 结果

2.2 WHERE子句的作用 #

WHERE子句就像一个"筛选器",它会检查每一行匹配到的数据,只保留满足条件的数据行。

3. 基本过滤条件 #

基本过滤是最常用的过滤方式,包括相等比较、不等比较等。

3.1 相等比较 #

查找属性值等于某个特定值的节点。

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", age: 30, city: "北京"}),
       (p2:Person {name: "李四", age: 25, city: "上海"}),
       (p3:Person {name: "王五", age: 30, city: "北京"}),
       (p4:Person {name: "赵六", age: 35, city: "广州"})

// 查找名字为"张三"的人
MATCH (p:Person)
WHERE p.name = "张三"
RETURN p

// 查找年龄等于30岁的人
MATCH (p:Person)
WHERE p.age = 30
RETURN p.name, p.age

// 查找城市为"北京"的人
MATCH (p:Person)
WHERE p.city = "北京"
RETURN p.name, p.city

3.2 不等比较 #

查找属性值不等于某个特定值的节点。

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", age: 30, city: "北京"}),
       (p2:Person {name: "李四", age: 25, city: "上海"}),
       (p3:Person {name: "王五", age: 30, city: "北京"}),
       (p4:Person {name: "赵六", age: 35, city: "广州"})

// 查找名字不等于"张三"的人
MATCH (p:Person)
WHERE p.name <> "张三"
RETURN p.name

// 查找年龄不等于30岁的人
MATCH (p:Person)
WHERE p.age <> 30
RETURN p.name, p.age

// 查找城市不是"北京"的人
MATCH (p:Person)
WHERE p.city <> "北京"
RETURN p.name, p.city

3.3 逻辑操作符(AND, OR, NOT) #

可以组合多个条件进行更复杂的过滤。

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", age: 30, city: "北京"}),
       (p2:Person {name: "李四", age: 25, city: "上海"}),
       (p3:Person {name: "王五", age: 20, city: "北京"}),
       (p4:Person {name: "赵六", age: 35, city: "广州"}),
       (p5:Person {name: "孙七", age: 28, city: "深圳"})

// 使用 AND:查找年龄大于25岁且小于35岁的人
MATCH (p:Person)
WHERE p.age > 25 AND p.age < 35
RETURN p.name, p.age

// 使用 OR:查找城市为"北京"或"上海"的人
MATCH (p:Person)
WHERE p.city = "北京" OR p.city = "上海"
RETURN p.name, p.city

// 使用 NOT:查找年龄不小于18岁的人(即年龄大于等于18岁)
MATCH (p:Person)
WHERE NOT p.age < 18
RETURN p.name, p.age

// 组合使用:查找(年龄大于25岁且小于35岁)或(城市为"北京")的人
MATCH (p:Person)
WHERE (p.age > 25 AND p.age < 35) OR p.city = "北京"
RETURN p.name, p.age, p.city

4. 范围查询 #

范围查询用于查找属性值在某个范围内的节点,比如查找年龄在某个区间的人,或者查找某个时间段内上映的电影。

4.1 前置知识:范围查询 #

范围查询就是查找数值在某个区间内的数据。比如:

  • 查找年龄在18-65岁之间的人
  • 查找价格在100-500元之间的商品
  • 查找在2020-2023年之间创建的数据

4.2 范围查询的语法 #

Cypher支持多种方式表示范围:

  1. 链式比较:3 <= age <= 7(最直观)
  2. AND组合:age >= 3 AND age <= 7(最灵活)
  3. BETWEEN关键字:age BETWEEN 3 AND 7(最简洁)

4.3 数值范围查询 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", age: 30}),
       (p2:Person {name: "李四", age: 25}),
       (p3:Person {name: "王五", age: 35}),
       (p4:Person {name: "赵六", age: 20}),
       (product1:Product {name: "书包", price: 150}),
       (product2:Product {name: "水杯", price: 50}),
       (product3:Product {name: "运动鞋", price: 300}),
       (m1:Movie {title: "长津湖", rating: 9.5}),
       (m2:Movie {title: "满江红", rating: 8.5}),
       (m3:Movie {title: "功夫", rating: 7.5})

// 方式1:使用链式比较(最直观)
MATCH (p:Person)
WHERE 25 <= p.age <= 35
RETURN p.name, p.age

// 方式2:使用 AND 组合(最灵活)
MATCH (p:Person)
WHERE p.age >= 25 AND p.age <= 35
RETURN p.name, p.age

// 方式3:使用 BETWEEN 关键字(最简洁)
MATCH (p:Person)
WHERE p.age BETWEEN 25 AND 35
RETURN p.name, p.age

// 查找价格在100到500之间的商品
MATCH (product:Product)
WHERE product.price >= 100 AND product.price <= 500
RETURN product.name, product.price

// 查找评分在8.0到10.0之间的电影
MATCH (m:Movie)
WHERE m.rating BETWEEN 8.0 AND 10.0
RETURN m.title, m.rating

4.4 日期范围查询 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (m1:Movie {title: "长津湖", released: 2021}),
       (m2:Movie {title: "满江红", released: 2023}),
       (m3:Movie {title: "功夫", released: 2019}),
       (p1:Person {name: "张三", created_at: date('2023-06-01')}),
       (p2:Person {name: "李四", created_at: date('2022-03-15')}),
       (c1:Company {name: "科技公司"}),
       (c2:Company {name: "互联网公司"})

CREATE (p1)-[:WORKS_FOR {start_date: date('2021-01-01')}]->(c1),
       (p2)-[:WORKS_FOR {start_date: date('2022-06-01')}]->(c2)

// 查找在2020年到2023年之间上映的电影
MATCH (m:Movie)
WHERE m.released >= 2020 AND m.released <= 2023
RETURN m.title, m.released
ORDER BY m.released

// 使用 BETWEEN 查找日期范围
MATCH (m:Movie)
WHERE m.released BETWEEN 2020 AND 2023
RETURN m.title, m.released

// 查找在某个日期之后创建的数据
MATCH (p:Person)
WHERE p.created_at >= date('2023-01-01')
RETURN p.name, p.created_at

// 查找在某个时间段内的工作关系
MATCH (p:Person)-[r:WORKS_FOR]->(c:Company)
WHERE r.start_date >= date('2020-01-01') 
  AND r.start_date <= date('2023-12-31')
RETURN p.name, c.name, r.start_date

5. 属性存在性检查 #

有时候我们需要查找具有某个属性的节点,或者查找没有某个属性的节点。这就是属性存在性检查。

5.1 前置知识:NULL值 #

在数据库中,如果一个属性不存在或者没有被设置,它的值就是NULL(空值)。NULL表示"没有值",与0、空字符串""或False都不同。

5.2 检查属性是否存在 #

使用IS NOT NULL检查属性是否存在,使用IS NULL检查属性是否不存在。

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", age: 30, email: "zhangsan@example.com"}),
       (p2:Person {name: "李四", age: 25, phone: "13800138000"}),
       (p3:Person {name: "王五", age: 35}),
       (p4:Person {name: "赵六", age: 28, email: "zhaoliu@example.com", phone: "13900139000"}),
       (m1:Movie {title: "长津湖", rating: 9.5}),
       (m2:Movie {title: "满江红", rating: 8.5, comment: "很好"}),
       (m3:Movie {title: "功夫", rating: 8.0})

// 查找有邮箱地址的人(邮箱属性存在且不为空)
MATCH (p:Person)
WHERE p.email IS NOT NULL
RETURN p.name, p.email

// 查找没有邮箱地址的人(邮箱属性不存在或为空)
MATCH (p:Person)
WHERE p.email IS NULL
RETURN p.name

// 查找有电话号码的人
MATCH (p:Person)
WHERE p.phone IS NOT NULL
RETURN p.name, p.phone

// 查找有评分但没有评论的电影
MATCH (m:Movie)
WHERE m.rating IS NOT NULL AND m.comment IS NULL
RETURN m.title, m.rating

// 组合使用:查找年龄大于25岁且有邮箱的人
MATCH (p:Person)
WHERE p.age > 25 AND p.email IS NOT NULL
RETURN p.name, p.age, p.email

6. 字符串匹配 #

字符串匹配用于查找属性值符合某种模式的节点,比如查找名字以某个字母开头的人,或者名字包含某个字符串的人。

6.1 前置知识:字符串匹配 #

字符串匹配就是检查一个字符串是否符合某种模式。比如:

  • 查找名字以"J"开头的人
  • 查找名字包含"an"的人
  • 查找名字以"n"结尾的人

6.2 字符串匹配的方式 #

Cypher提供了多种字符串匹配方式:

  1. STARTS WITH:检查字符串是否以指定前缀开头
  2. ENDS WITH:检查字符串是否以指定后缀结尾
  3. CONTAINS:检查字符串是否包含指定子串
  4. 正则表达式(=~):使用正则表达式进行复杂匹配

6.3 基本字符串匹配 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", email: "zhangsan@gmail.com"}),
       (p2:Person {name: "张译", email: "zhangyi@example.com"}),
       (p3:Person {name: "李四", email: "lisi@qq.com"}),
       (p4:Person {name: "吴京", email: "wujing@gmail.com"}),
       (m1:Movie {title: "功夫"}),
       (m2:Movie {title: "长津湖"}),
       (m3:Movie {title: "满江红"})

// 使用 STARTS WITH:查找名字以"张"开头的人
MATCH (p:Person)
WHERE p.name STARTS WITH "张"
RETURN p.name

// 使用 ENDS WITH:查找名字以"三"结尾的人
MATCH (p:Person)
WHERE p.name ENDS WITH "三"
RETURN p.name

// 使用 CONTAINS:查找名字包含"京"的人
MATCH (p:Person)
WHERE p.name CONTAINS "京"
RETURN p.name

// 查找邮箱以"gmail.com"结尾的人
MATCH (p:Person)
WHERE p.email ENDS WITH "gmail.com"
RETURN p.name, p.email

// 查找标题包含"功夫"的电影
MATCH (m:Movie)
WHERE m.title CONTAINS "功夫"
RETURN m.title

// 组合使用:查找名字以"张"开头且包含"译"的人
MATCH (p:Person)
WHERE p.name STARTS WITH "张" AND p.name CONTAINS "译"
RETURN p.name

6.4 正则表达式匹配(高级) #

正则表达式可以用于更复杂的字符串匹配

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三", email: "zhangsan@example.com"}),
       (p2:Person {name: "李四", email: "lisi@gmail.com"}),
       (p3:Person {name: "王五", email: "wangwu@qq.com"}),
       (p4:Person {name: "John", email: "john@example.com"}),
       (p5:Person {name: "用户123", email: "user123@test.com"})

// 使用正则表达式:查找名字以"张"或"李"开头的人
// =~ 是正则表达式匹配操作符
MATCH (p:Person)
WHERE p.name =~ "^[张李].*"
RETURN p.name

// 查找邮箱格式正确的人
MATCH (p:Person)
WHERE p.email =~ ".*@.*\\..*"
RETURN p.name, p.email

// 查找名字包含数字的人
MATCH (p:Person)
WHERE p.name =~ ".*[0-9].*"
RETURN p.name

// 查找以大写字母开头的名字
MATCH (p:Person)
WHERE p.name =~ "^[A-Z].*"
RETURN p.name

// 注意:正则表达式中的点号需要转义为 \\. 才能匹配实际的点号

7. 模式过滤 #

模式过滤允许你在WHERE子句中使用图模式作为条件。比如查找"有朋友关系但没有工作关系"的人。

7.1 前置知识:模式作为条件 #

在WHERE子句中,你不仅可以检查节点的属性,还可以检查节点之间的关系模式。比如:

  • 检查一个人是否有朋友关系
  • 检查一个人是否参演过电影
  • 检查一个人是否既参演又执导过电影

7.2 检查关系是否存在 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三"}),
       (p2:Person {name: "李四"}),
       (p3:Person {name: "王五"}),
       (p4:Person {name: "赵六"}),
       (m1:Movie {title: "长津湖"}),
       (m2:Movie {title: "满江红"}),
       (c1:Company {name: "科技公司"})

CREATE (p1)-[:IS_FRIENDS_WITH]->(p2),
       (p2)-[:IS_FRIENDS_WITH]->(p3),
       (p1)-[:ACTED_IN]->(m1),
       (p1)-[:DIRECTED]->(m2),
       (p2)-[:ACTED_IN]->(m1),
       (p4)-[:WORKS_FOR]->(c1)

// 查找有朋友关系的人
MATCH (p:Person)
WHERE (p)-[:IS_FRIENDS_WITH]->()
RETURN p.name

// 查找没有朋友关系的人
MATCH (p:Person)
WHERE NOT (p)-[:IS_FRIENDS_WITH]->()
RETURN p.name

// 查找既参演又执导过电影的人
MATCH (p:Person)
WHERE (p)-[:ACTED_IN]->() AND (p)-[:DIRECTED]->()
RETURN p.name

// 查找参演过电影但没有执导过电影的人
MATCH (p:Person)
WHERE (p)-[:ACTED_IN]->() AND NOT (p)-[:DIRECTED]->()
RETURN p.name

// 查找有工作关系但没有朋友关系的人
MATCH (p:Person)
WHERE (p)-[:WORKS_FOR]->() AND NOT (p)-[:IS_FRIENDS_WITH]->()
RETURN p.name

8. 可选匹配(OPTIONAL MATCH) #

OPTIONAL MATCH是MATCH的可选版本。即使模式不匹配,也会返回结果(不匹配的部分为null)。

8.1 前置知识:MATCH vs OPTIONAL MATCH #

  • MATCH:必须匹配,如果模式不匹配,这一行就不会出现在结果中
  • OPTIONAL MATCH:可选匹配,即使模式不匹配,这一行也会出现在结果中,只是不匹配的部分为null

8.2 为什么需要OPTIONAL MATCH? #

有时候我们需要显示所有节点,无论它们是否有某种关系。比如:

  • 显示所有人,无论他们是否有工作
  • 显示所有电影,无论它们是否有演员
  • 显示所有产品,无论它们是否有评论

8.3 基本用法 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三"}),
       (p2:Person {name: "李四"}),
       (p3:Person {name: "王五"}),
       (c1:Company {name: "科技公司"}),
       (m1:Movie {title: "长津湖"}),
       (m2:Movie {title: "满江红"}),
       (product1:Product {name: "书包"}),
       (product2:Product {name: "水杯"}),
       (r1:Review {content: "很好"})

CREATE (p1)-[:WORKS_FOR]->(c1),
       (p1)-[:ACTED_IN]->(m1),
       (r1)-[:REVIEWED]->(product1)

// 显示所有人,无论他们是否有工作关系
MATCH (p:Person)
OPTIONAL MATCH (p)-[:WORKS_FOR]->(c:Company)
RETURN p.name, c.name AS company

// 显示所有电影,无论它们是否有演员
MATCH (m:Movie)
OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Person)
RETURN m.title, collect(a.name) AS actors

// 显示所有产品,无论它们是否有评论
MATCH (product:Product)
OPTIONAL MATCH (product)<-[:REVIEWED]-(r:Review)
RETURN product.name, count(r) AS review_count

// 对比:使用 MATCH(必须匹配)
MATCH (p:Person)-[:WORKS_FOR]->(c:Company)
RETURN p.name, c.name
// 只返回有工作关系的人

// 使用 OPTIONAL MATCH(可选匹配)
MATCH (p:Person)
OPTIONAL MATCH (p)-[:WORKS_FOR]->(c:Company)
RETURN p.name, c.name
// 返回所有人,没有工作关系的显示为 null

9. 复杂模式查询 #

可以组合多个模式进行更复杂的查询,比如查找"朋友的朋友"、"喜欢相同技术的人"等。

9.1 多跳关系查询 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三"}),
       (p2:Person {name: "李四"}),
       (p3:Person {name: "王五"}),
       (p4:Person {name: "赵六"}),
       (m1:Movie {title: "长津湖"}),
       (m2:Movie {title: "满江红"})

CREATE (p1)-[:IS_FRIENDS_WITH]->(p2),
       (p2)-[:IS_FRIENDS_WITH]->(p3),
       (p3)-[:IS_FRIENDS_WITH]->(p4),
       (p1)-[:ACTED_IN]->(m1),
       (p2)-[:ACTED_IN]->(m1),
       (p3)-[:ACTED_IN]->(m2),
       (p1)-[:DIRECTED]->(m1),
       (p4)-[:ACTED_IN]->(m1)

// 查找朋友的朋友(2跳关系)
MATCH (p:Person)-[:IS_FRIENDS_WITH*2]->(friend_of_friend:Person)
RETURN p.name, friend_of_friend.name

// 查找朋友的朋友的朋友(3跳关系)
MATCH (p:Person)-[:IS_FRIENDS_WITH*3]->(fofof:Person)
RETURN p.name, fofof.name

// 查找1到3跳的朋友关系
MATCH (p:Person)-[:IS_FRIENDS_WITH*1..3]->(friend:Person)
RETURN p.name, friend.name

// 查找参演同一部电影的其他演员(通过电影节点连接)
MATCH (a1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(a2:Person)
WHERE a1 <> a2
RETURN a1.name AS actor1, a2.name AS actor2, m.title AS movie

// 查找导演执导的电影中的演员
MATCH (d:Person)-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN d.name AS director, m.title AS movie, a.name AS actor

9.2 查找有共同兴趣的人 #

// 清空数据库
MATCH (n) DETACH DELETE n

// 创建测试数据
CREATE (p1:Person {name: "张三"}),
       (p2:Person {name: "李四"}),
       (p3:Person {name: "王五"}),
       (tech1:Technology {name: "Python"}),
       (tech2:Technology {name: "Java"}),
       (u1:User {name: "用户1"}),
       (u2:User {name: "用户2"}),
       (product1:Product {name: "书包"}),
       (hobby1:Hobby {name: "编程"}),
       (m1:Movie {title: "长津湖"}),
       (m2:Movie {title: "满江红"}),
       (g1:Genre {name: "动作"})

CREATE (p1)-[:IS_FRIENDS_WITH]->(p2),
       (p1)-[:LIKES]->(tech1),
       (p2)-[:LIKES]->(tech1),
       (p1)-[:LIKES]->(hobby1),
       (p2)-[:LIKES]->(hobby1),
       (u1)-[:PURCHASED]->(product1),
       (u2)-[:PURCHASED]->(product1),
       (p1)-[:ACTED_IN]->(m1),
       (p2)-[:ACTED_IN]->(m2),
       (m1)-[:BELONGS_TO]->(g1),
       (m2)-[:BELONGS_TO]->(g1)

// 查找喜欢相同技术的人
MATCH (p1:Person)-[:LIKES]->(tech:Technology)<-[:LIKES]-(p2:Person)
WHERE p1 <> p2
RETURN p1.name AS person1, p2.name AS person2, tech.name AS common_interest

// 查找购买过相同商品的人
MATCH (u1:User)-[:PURCHASED]->(product:Product)<-[:PURCHASED]-(u2:User)
WHERE u1 <> u2
RETURN u1.name AS user1, u2.name AS user2, product.name AS common_product

// 查找有共同爱好的朋友
MATCH (p1:Person)-[:IS_FRIENDS_WITH]->(p2:Person),
      (p1)-[:LIKES]->(hobby:Hobby)<-[:LIKES]-(p2)
RETURN p1.name AS person1, p2.name AS person2, hobby.name AS common_hobby

// 查找参演过相同类型电影的人
MATCH (a1:Person)-[:ACTED_IN]->(m:Movie)-[:BELONGS_TO]->(g:Genre)<-[:BELONGS_TO]-(m2:Movie)<-[:ACTED_IN]-(a2:Person)
WHERE a1 <> a2 AND m <> m2
RETURN DISTINCT a1.name AS actor1, a2.name AS actor2, g.name AS genre

10. 小结 #

10.1 核心概念 #

概念 说明 主要用途
WHERE子句 过滤查询结果 根据条件筛选数据
范围查询 查询数值范围 查找在某个区间内的数据
属性检查 检查属性是否存在 查找有/没有某个属性的节点
字符串匹配 字符串模式匹配 查找符合某种模式的字符串
模式过滤 使用模式作为条件 根据关系模式筛选数据
OPTIONAL MATCH 可选匹配 显示所有节点,无论是否有关系

10.2 查询优化建议 #

  1. 在MATCH中尽可能指定标签和属性:这样可以缩小搜索范围,提高查询效率
  2. 使用WHERE子句处理复杂条件:对于需要组合多个条件的查询,使用WHERE子句更清晰
  3. 合理使用LIMIT:当结果很多时,使用LIMIT可以避免返回过多数据
  4. 使用索引:为常用查询字段创建索引可以提高查询速度(高级主题,后续教程会介绍)

10.3 最佳实践 #

  • 在MATCH中尽可能指定标签和属性
  • 使用WHERE子句处理复杂条件
  • 使用DISTINCT去除重复结果
  • 使用LIMIT限制大型查询结果
  • 使用OPTIONAL MATCH显示所有数据(即使没有关系)
← 上一节 37.GraphRAG 下一节 39.结果处理和聚合 →

访问验证

请输入访问令牌

Token不正确,请重新输入