Neo4j将多行聚合成一个映射

时间:2015-06-08 18:23:38

标签: neo4j cypher aggregate

我有以下Cypher脚本:

MATCH (sy:SchoolYear)<-[:TERM_OF*]-()<-[:DAY_OF]-(d:Day)
WHERE sy.year = 2015
OPTIONAL MATCH (d)<-[:START]-(e:Enrollment)-[:AT]->(s:School)
RETURN d.date, s.abbreviation, count(e)
ORDER BY d.date

这为我提供了我想要的范围内的所有日期,并返回在该日期为每所学校注册的学生人数,或者为null。我唯一的问题是不同的学校在不同的行上,导致一个日期有多行。我希望每个日期将这些汇总成一行。

我给了:

1/1/2000, School 1, 5
1/1/2000, School 2, 10
1/2/2000, null, null
1/3/2000, School 1, 6

我想要的是什么:

1/1/2000, {School 1 : 5, School 2: 10}
1/2/2000, null
1/3/2000, {School 1: 6}

我试过了:

MATCH (sy:SchoolYear)<-[TERM_OF*]-()<-[:DAY_OF]-(d:Day)
WHERE sy.year = 2015
OPTIONAL MATCH (d)<-[:START]-(e:Enrollment)-[:AT]->(s:School)
WITH d, s.abbreviation as abb, count(e) as enr
RETURN d.date, {abb:enr}
ORDER BY d.date

我应该怎么做?

2 个答案:

答案 0 :(得分:4)

以下是我将每个学校聚合成地图并将地图集成到集合中的方法

MATCH (sy:SchoolYear)<-[TERM_OF*]-()<-[:DAY_OF]-(d:Day)
WHERE sy.year = 2015
OPTIONAL MATCH (d)<-[:START]-(e:Enrollment)-[:AT]->(s:School)
WITH  d, s, count(e) as students
RETURN d.date, collect({name:s.abbreviation, students:students})
ORDER BY d.date

答案 1 :(得分:2)

这有点难看,但我认为它会回归你所追求的。我尝试使用学校名称作为关键,就像你在你的例子中所做的那样,我也无法使用它。最后我采取了这个。

MATCH (sy:SchoolYear)<-[TERM_OF*]-()<-[:DAY_OF]-(d:Day)
WHERE sy.year = 2015
OPTIONAL MATCH (d)<-[:START]-(e:Enrolment)-[:AT]->(s:School)
// collect the schools and their counts together
with d, [s.abbreviation, count(e)] as school_count
// collect all of the school counts together by date
with d.date as date, collect(school_count) as school_counts
// format the school counts as a string with the schools
// as keys and the counts as values
with  date, reduce( out = "", s in school_counts | out + s[0] + " : " + s[1] + ", " ) as school_count_str
return  date, '{ ' + left(school_count_str, length(school_count_str)-2) + ' }' as school_counts
order by date