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