NEO4J-Cypher图数据库查询语言(5)

1,869 阅读5分钟

Cypher图数据库查询语言(1) :Cypher概述

Cypher图数据库查询语言(2) :Cypher基本语法

Cypher图数据库查询语言(3) :Cypher语句-MATCH,OPTIONAL MATCH

Cypher图数据库查询语言(4) :Cypher语句-WHERE

Cypher图数据库查询语言(5) :Cypher语句-START,Aggregation 和 LOAD CSV

Cypher图数据库查询语言(6) :Cypher语句-CREATE,MERGR

Cypher图数据库查询语言(7) :Cypher语句-SET,DELETE,REMOVE

Cypher图数据库查询语言(8) :Cypher语句-FOREACH,CREATE UNIQUE

Cypher图数据库查询语言(9) :Cypher语句-RETURN,ORDER BY

Cypher图数据库查询语言(10) :Cypher语句-LIMIT,SKIP

Cypher图数据库查询语言(11) :Cypher语句-WITH,UNWIND,UNION,CALL

语句可分为三类,包括读语句、写语句和通用语句。

  • 读语句:MATCH、OPTIONAL MATCH、WHERE、START、Aggregation和LOAD CSV。
  • 写语句:CREATE、MERGR、SET、DELETE、REMOVE、FOREACH和CREATE UNIQUE。
  • 通用语句:RETURN、ORDER BY、LIMIT、SKIP、WITH、UNWIND、UNION和CALL。

4 START

通过遗留索引 (Legancy Index) 查找节点。

START 语句应当仅用于访问遗留的索引。所有其他的情况,都应使用MATCH代替。

4.1 通过索引获取节点

4.1.1 通过索引搜索 (Index Seek) 获取节点

当采用索引搜索查找开始点时,可以这样做:node:index-name(key="value")。在本例中存在一个名为nodes的节点索引。

START n = node:nodes(name = 'A')
RETURN n

4.1.2 通过索引查询 (Index Query) 获取节点

当采用复杂的 Lucene 查询来查找开始点时,语法为:node:index-name("query")。这样可以写出很高级的索引查询。

START n = node:nodes("name:A")
RETURN n

4.2 通过索引获取关系

4.2.1 通过索引搜索 (Index Seek) 获取关系

当采用索引搜索查找开始点时,可以这样做:relationship:index-name(key="value")。在本例中存在一个名为rels的关系索引。

START r = relationship:rels(name = 'Andres')
RETURN r

5 Aggregation

5.1 简介

Cypher支持使用聚合 (Aggregation)来计算聚在一起的数据,类似SQL中的group by。聚合函数有多个输入值,然后基于它们计算出一个聚合值。例如,avg函数计算多个数值的平均值,min函数用于找到一组值中最小的那个。

聚合可以在匹配到的子图上进行计算。非聚合的表达式将值聚集起来,然后放入聚合函数。

例如,下面的返回语句:

RETURN n, count(*)

这里有两个表达式:n 和 count(*)。前者n不是聚合函数,是一个分组键。后者count()是一个聚合函数。因此,根据不同的分组键 (Grouping Key) ,匹配的子图将被分为不同的组。聚合函数将运行在这些组上来计算聚合值。

查询:

MATCH (me:Person) --> (friend:Person) --> (friend_of_friend:Person)
WHERE me.name = 'A'
RETURN count(DISTINCT friend_of_friend), count(friend_of_friend)

在这个例子中,试图找到朋友的所有朋友并计算朋友的个数。当没有使用DISTINCT时,因为B和C都认识D,因此D被计算了两次。

结果:

count(DISTINCT friend_of_friend) count(friend_of_friend)
1 2

5.2 COUNT

count用于计算行的数量。

count有两种使用方式:count(*)用于计算匹配的行数,而count()用于计算中非空值的数量。

5.2.1 计算节点

计算节点的数量。例如:如果要计算连接到某个节点的节点数,可用count(*)。

查询:

MATCH (n { name:'A'}) --> (x)
RETURN n, count(*)

结果: 返回了开始节点及与之相连节点的数量。

n count(*)
Node[0] {name:"A",property:13} 3

5.2.2 按组计算关系类型的数量

计算关系类型组中的数量,返回类型和数量。

查询:

MATCH (n { name:'A'}) -[r]-> ()
RETURN type(r), count(*)

结果: 返回关系类型和关系组中的关系数量。

type(r) count(*)
"KNOWS" 3

5.2.3 计算实体

除了通过 count(*) 计算结果的数量,还可以加入你关心的name值。

查询:

MATCH (n { name:'A'}) --> (x)
RETURN count(x)

结果: 返回与满足带有name属性值为'A'的节点相连的所有节点的数量。

count(x)
3

5.2.4 计算非空值的数量

可以通过count()来计算非空值的数量。

查询:

MATCH (n:Person)
RETURN count(n.property)

结果: 返回了property属性非空的所有节点。

count(n.property)
3

5.3 统计

5.3.1 sum

聚合函数sum简单地计算所有值之和。计算的时候,空值将被丢弃。

查询:

MATCH (n:Person)
RETURN sum(n.property)

结果: 返回包含Person标签的所有节点的property属性值的和。

sum(n.property)
90

5.3.2 avg

avg计算数值列的平均值。

查询:

MATCH (n:Person)
RETURN avg(n.property)

结果: 返回property属性值的平均值。

avg(n.property)
30.0

5.3.3 percentileDisc

percentileDisc计算给定值在一个组中的百分位,取值从0.0到1.0.它使用舍入法,返回最接近百分位的值。对于插值法,请参考percentileCount函数。

查询:

MATCH (n:Person)
RETURN percentileDisc(n.property, 0.5)

结果:

percentileDisc(n.property, 0.5)
33

5.3.4 percentileCount

percentileCount计算给定值在一个组中的百分位,百分位的值从0.0到1.0。它采用线性插值的方法,在两个值之间计算一个加权平均数。

查询:

MATCH (n:Person)
RETURN percentileCount(n.property, 0.4)

结果:

percentileCount(n.property, 0.4)
29.0

5.3.5 stdev

stdev计算给定值在一个组中的标准偏差。它采用标准的two-pass方法,以N-1作为分母。当以部分样本作为无偏估计时使用stdev;当计算整个样本的标准偏差时,应该使用stdevp。

查询:

MATCH (n)
WHERE n.name IN ['A','B','C']
RETURN stdev(n.property)

结果:

stdev(n.property)
15.716233645501712

5.3.6 stdevp

stdevp计算给定值在一个组中的标准偏差。与stdev类似,区别如上所述。

查询:

MATCH (n)
WHERE n.name IN ['A','B','C']
RETURN stdevp(n.property)

结果:

stdevp(n.property)
12.832251036613439

5.3.7 max

max查找数值列中的最大值。

查询:

MATCH (n:Person)
RETURN max(n.property)

结果:返回了property属性中的最大值。

max(n.property)
44

5.3.8 min

min查找数值列中的最小值。

查询:

MATCH (n:Person)
RETURN min(n.property)

结果:返回了property属性中的最小值。

min(n.property)
13

5.4 Collect

collect将所有值收集起来放入一个列表,空值null将被忽略。

查询:

MATCH (n:Person)
RETURN collect(n.property)

结果:以列表的形式返回收集到的值。

collect(n.property)
[13,33,44]

5.5 DISTINCT

所有的聚合函数都可以带有DISTINCT修饰符,它将去掉其中的重复值。因此,计算节点中不重复眼睛颜色数量的查询可以这样写:

查询:

MATCH (a:Person { name:'A'})-->(b)
RETURN count(DISTINCT b.eyes)

结果:

count(DISTINCT b.eyes)
2

6 LOAD CSV

导入CSV文件见如下链接