1.15 WITH
WITH语句将分段的查询部分连接在一起,查询结果从一部分以管道形式传递给另外一部分作为开始点。
使用WITH可以在将结果传递到后续查询之前对结果进行操作。操作可以是改变结果的形式或者数量。WITH的一个常见用法就是限制传递给其他MATCH语句的结果数。通过结合ORDER BY和LIMIT,可获取排在前面的X个结果。
1.15.1 过滤聚合函数结果
聚合的结果必须要通过WITH语句传递才能进行过滤。
MATCH (david { name: 'Tom Hanks' })--()--(otherPerson) WITH otherPerson, count(*) AS foaf WHERE foaf > 1 RETURN otherPerson |
1.15.2 在collect前对结果排序
可以在将结果传递给collect函数之前对结果进行排序,这样就可以返回排过序的列表。
MATCH (n) WITH n ORDER BY n.name DESC LIMIT 3 RETURN collect(n.name) |
1.15.3 限制路径搜索的分支
可以限制匹配路径的数量,然后以这些路径为基础再做任何类似的有限制条件的搜索。
MATCH (n { name: 'Tom Hanks' })--(m) WITH m ORDER BY m.name DESC LIMIT 1 MATCH (m)--(o) RETURN o.name |
1.16 FOREACH
FOREACH语句用于循环遍历结果集列表,然后做一些操作。
列表(lists)和路径(paths)是Cypher中的关键概念。可以使用FOREACH来更新其中的数据。它可以在路径或者聚合的列表的每个元素上执行更新命令。FOREACH括号中的变量是与外部分开的,这意味着FOREACH中创建的变量不能用于该语句之外。
在FOREACH括号内,可以执行任何的更新命令,包括CREATE,CREATE UNIQUE,DELETE和FOREACH。如果希望对列表中的每个元素执行额外的MATCH命令,使用UNWIND命令更合适。
1.16.1 标记路径上的所有节点
这个查询将设置路径上所有节点的marked属性为true值。
MATCH p = (root { name: 'root' })-[r]-(A) FOREACH (n IN nodes(p)| SET n.marked = TRUE ) |
1.16.2 从列表中创建朋友
下面的查询将列表中的人全部加为'A'的朋友。
MATCH (a {name: 'root' }) FOREACH (name IN ["Mike", "Carl", "Bruce"] | CREATE (a)-[:FRIEND]->(:Person {name: name})) |
1.17 Aggregation
Cypher支持使用聚合(Aggregation)来计算聚在一起的数据,类似SQL中的group by。聚合函数有多个输入值,然后基于它们计算出一个聚合值
RETURN n, count(*) |
1.17.1 Count
count用于计算行的数量。
(1)计算节点
MATCH (n :Person) RETURN count(*) |
(2)按组计算关系类型的数量
计算关系类型组中的数量,返回类型和数量。
MATCH (n { name: 'Tom Hanks' })-[r]->() RETURN type(r), count(*) |
(3)计算非空值的数量
可以通过count(expression)来计算非空值的数量。
MATCH (n) RETURN count(n.title) |
1.17.2 统计
CREATE (A :Person{name: 'A', property:13 }),(B :Person { name: 'B', property:33,eyes: 'blue' }),(C:Person { name: 'C', property:44,eyes: 'blue' }),(D:Person { name: 'D', eyes: 'blue' }) return A,B,C,D |
(1)sum
聚合函数sum简单地计算所有值之和。计算的时候,空值将被丢弃。
MATCH (n:Person) RETURN sum(n.property) |
返回包含Person标签的所有节点的property属性值的和。
(2)avg
avg计算数值列的平均值。
MATCH (n:Person) RETURN avg(n.property) |
返回property属性值的平均值。
(3)percentileDisc
percentileDisc计算给定值在一个组中的百分位,取值从0.0到1.0。它使用舍入法,返回最接近百分位的值。对于插值法,请参考percentileCont小节。
MATCH (n:Person) RETURN percentileDisc(n.property, 0.5) |
(4)percentileCont
percentileCont计算给定值在一个组中的百分位,百分位的值从0.0到1.0。
MATCH (n:Person) RETURN percentileCont(n.property, 0.4) |
(5)stdev
stddev计算给定值在一个组中的标准偏差。
MATCH (n) WHERE n.name IN ['A', 'B', 'C'] RETURN stdev(n.property) |
(6)stdevp
stdevp计算给定值在一个组中的标准偏差。
MATCH (n) WHERE n.name IN ['A', 'B', 'C'] RETURN stdevp(n.property) |
(7)max
max查找数值列中的最大值。
MATCH (n:Person) RETURN max(n.property) |
返回了property属性中的最大值。
(8)min
min查找数值列中的最小值。
MATCH (n:Person) RETURN min(n.property) |
返回了property属性中的最小值。
1.17.3 collect
collect将所有的值收集起来放入一个列表。空值null将被忽略。
MATCH (n:Person) RETURN collect(n.property) |
以列表的形式返回收集到的值。
1.17.4 DISTINCT
所有的聚合函数都可以带有DISTINCT修饰符,它将去掉其中的重复值。
计算节点中不重复眼睛颜色数量的查询可以这样写:
MATCH (b) RETURN count(DISTINCT b.eyes) |
1.18 UNWIND
UNWIND将一个列表展开为一个行的序列(行转列)。
1.18.1 UNWIND列表
将一个常量列表转为名为x的行并返回。
UNWIND [1, 2, 3] AS x RETURN x |
1.18.2 创建唯一列表
使用DISTINCT将一个重复值列表转为一个集合。
WITH [1, 1, 2, 2] AS coll UNWIND coll AS x WITH DISTINCT x RETURN collect(x) AS SET |
1.19 UNION
UNION语句用于将多个查询结果组合起来。
1.19.1 组合两个查询
用UNION ALL将两个查询的结果组合在一起,可能包含重复行。
MATCH (n:Actor) RETURN n.name AS name UNION ALL MATCH (n:Movie) RETURN n.title AS name |
1.19.2 组合两个查询并移除重复值
在UNION中不使用ALL时,组合的结果集中会去掉重复值。
MATCH (n:Actor) RETURN n.name AS name UNION MATCH (n:Movie) RETURN n.title AS name |
1.20 CALL
CALL语句用于调用数据库中的过程(procedure)。
1.20.1 调用过程
本例调用数据库内嵌的过程db.labels,它可列出数据库中的所有标签。
CALL db.labels |
1.20.2 使用命名空间和名字调用过程
本例调用数据库内嵌的过程db.labels,它可列出数据库中的所有标签。
CALL `db`.`labels` |
1.20.3 使用字面值参数调用过程
下面使用字面值参数调用了例子中的过程org.neo4j.procedure.example.addNodeToIndex,如参数直接写在语句中。
CALL org.neo4j.procedure.example.addNodeToIndex('users', 0, 'name') |
因为例子中的过程不返回任何结果,因此结果返回空。
1.20.4 在复杂查询中调用过程
这里调用数据库内嵌的过程db.labels计算数据库中的总标签数。
CALL db.labels() YIELD label RETURN count(label) AS numLabels |
1.20.5 在复杂查询中调用过程并重命名结果
这里调用内嵌过程db.propertyKeys作为一部分,计算数据库中包含每个属性键的节点数。
CALL db.propertyKeys() YIELD propertyKey AS prop MATCH (n) WHERE n[prop] IS NOT NULL RETURN prop, count(n) AS numNodes |