关于 YMatrix
部署数据库
使用数据库
管理集群
最佳实践
高级功能
高级查询
联邦查询
Grafana 监控
备份恢复
灾难恢复
图数据库
管理手册
性能调优
故障诊断
工具指南
系统配置参数
SQL 参考
使用 WITH,你可以在输出传递给后续查询部分之前对其进行操作。操作可以改变结果集中条目的形状和/或数量。
WITH 也可以像 RETURN 一样,使用别名将表达式引入结果中。
WITH 还用于将图的读取与图的更新分离。查询的每个部分必须是只读或只写的。从写入子句转到读取子句时,可以使用可选的 WITH 来实现。
在 YMatrix AGE 中,WITH 的场景主要有:
中间处理(管道)
WITH 相当于查询中间的一个"管道",把前面的结果处理一下再传给后面。
MATCH (p:Person) WITH p ORDER BY p.age DESC LIMIT 3 RETURN p.name,
先匹配所有 Person,用 WITH 按年龄排序取前 3 个,再返回名字。没有 WITH 的话,RETURN 只能一步到位,无法做这种中间筛选。
别名(和 RETURN 类似)
MATCH (p:Person) WITH p.name AS name, p.age AS age WHERE age > 30 RETURN name,
WITH 把表达式重命名,后续子句用新名字引用。
读写分离
Cypher 规定:一个查询片段要么只读,要么只写。CREATE 是写操作,MATCH/WHERE 是读操作。如果你想先写再读,必须用 WITH 隔开。
CREATE (a:Person {name: 'Tom'}) WITH a MATCH (a)-[:KNOWS]->(b) RETURN b,
没有中间的 WITH a,直接从 CREATE 跳到 MATCH 会报错,因为混合了读写。
全局排序 在 YMatrix AGE 中,order by 不保证全局有序。因此 order by + limit 不保证取 全局有序的前三个。 如果需要保证全局有序,需要在ORDER BY 之前使用WITH 语句。
RETURN p ORDER BY p.age LIMIT 3 → 每个 segment 各自排序取前 3,最终结果不一定是全局的前 3。WITH p ORDER BY p.age LIMIT 3 RETURN p → WITH 会触发数据汇聚(Motion 节点),在汇聚后做全局排序再取前 3。聚合结果必须通过 WITH 子句才能进行过滤。
查询
SELECT *
FROM cypher('graph_name', $$
MATCH (david {name: 'David'})-[]-(otherPerson)-[]->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1
RETURN otherPerson.name
$$) as (name agtype);
查询将返回与 'David' 连接的、至少有一个以上出边关系的人的名字。
结果
| name |
| -------- |
| "Anders" |
(1 row)
你可以在将结果传递给 collect 之前对其排序,从而对生成的列表进行排序。
查询
SELECT *
FROM cypher('graph_name', $$
MATCH (n) WITH n
ORDER BY n.name DESC LIMIT 3
RETURN collect(n.name)
$$) as (names agtype);
返回按名称逆序排列的人名列表,限制为 3 个,以列表形式返回。
结果
| names |
| ------------------------- |
| ["Emil","David","Ceasar"] |
1 row
你可以匹配路径,限制到一定数量,然后使用这些路径作为基础再次匹配,以及任意数量的类似限制搜索。
查询
SELECT *
FROM cypher('graph_name', $$
MATCH (n {name: 'Anders'})-[]-(m) WITH m
ORDER BY m.name DESC LIMIT 1
MATCH (m)-[]-(o)
RETURN o.name
$$) as (name agtype);
从 'Anders' 开始,找到所有匹配的节点,按名称降序排列并获取第一个结果,然后找到与该结果连接的所有节点,并返回它们的名称。
结果
| name |
| --------- |
| "Anders" |
| "Bossman" |
(2 rows)