Neo4j - 无法在聚合函数

时间:2017-04-01 13:17:19

标签: neo4j cypher graph-databases

大家好!我有一个Neo4j数据库,其中包含有关在特定时刻访问多个检查点的访问者的信息。访问者,访问和检查点表示为节点。

每个访问者都由他/她的设备MAC地址标识,每个检查点都有唯一的ID。

每个访问节点都包含一个EnterTime属性,该属性是在相应检查点附近首次发现具有某些特定MAC地址的访问者时的时间(自1970年以来的毫秒数)。

注意:访问的持续时间应计算为下次访问的EnterTime与此次访问的EnterTime之间的差异。

我的目标是找一些有关访问的统计信息,例如, 1)特定访客的平均访问时间, 2)访问特定商店的平均时间, 3)最受欢迎的商店(即具有最长总访问时间的商店) 4)最受欢迎的商店(即具有最长AVERAGE访问时间的商店)等。

使用此密码查询创建数据库:

//Create visitors:
CREATE (Visitor1: Visitor {MAC:'00:0a:95:9d:68:16'})
CREATE (Visitor2: Visitor {MAC:'00:0a:95:9d:68:17'})
CREATE (Visitor3: Visitor {MAC:'00:0a:95:9d:68:18'})

//Create CheckPoints:
CREATE (CheckPoint1: CheckPoint {CheckPointId: 1})
CREATE (CheckPoint2: CheckPoint {CheckPointId: 2})
CREATE (CheckPoint3: CheckPoint {CheckPointId: 3})
CREATE (CheckPoint4: CheckPoint {CheckPointId: 4})
CREATE (CheckPoint5: CheckPoint {CheckPointId: 5})


//Create visits:
//by visitor 1:
CREATE  (Visitor1)-[:MAKES]->(Visit1: Visit {EnterTime: 1488358800000})-[:TO]->(CheckPoint1)
CREATE  (Visitor1)-[:MAKES]->(Visit2: Visit {EnterTime: 1488359400000})-[:TO]->(CheckPoint2)
CREATE  (Visitor1)-[:MAKES]->(Visit3: Visit {EnterTime: 1488361200000})-[:TO]->(CheckPoint3)
CREATE  (Visitor1)-[:MAKES]->(Visit4: Visit {EnterTime: 1488363600000})-[:TO]->(CheckPoint4)
CREATE  (Visitor1)-[:MAKES]->(Visit5: Visit {EnterTime: 1488364800000})-[:TO]->(CheckPoint5)
CREATE  (Visitor1)-[:MAKES]->(Visit6: Visit {EnterTime: 1488365400000})-[:TO]->(CheckPoint1)

//by visitor 2:
CREATE  (Visitor2)-[:MAKES]->(Visit7: Visit {EnterTime: 1488358800000})-[:TO]->(CheckPoint1)
CREATE  (Visitor2)-[:MAKES]->(Visit8: Visit {EnterTime: 1488360300000})-[:TO]->(CheckPoint4)
CREATE  (Visitor2)-[:MAKES]->(Visit9: Visit {EnterTime: 1488362400000})-[:TO]->(CheckPoint2)
CREATE  (Visitor2)-[:MAKES]->(Visit10: Visit {EnterTime: 1488363000000})-[:TO]->(CheckPoint1)

//by visitor 3:
CREATE  (Visitor3)-[:MAKES]->(Visit11: Visit {EnterTime: 1488353820000})-[:TO]->(CheckPoint1)
CREATE  (Visitor3)-[:MAKES]->(Visit12: Visit {EnterTime: 1488354600000})-[:TO]->(CheckPoint4)
CREATE  (Visitor3)-[:MAKES]->(Visit13: Visit {EnterTime: 1488358200000})-[:TO]->(CheckPoint3)
CREATE  (Visitor3)-[:MAKES]->(Visit14: Visit {EnterTime: 1488359700000})-[:TO]->(CheckPoint1)  

请帮我正确地写下问题1 - 4。 到目前为止,我有这个查询,它将特定访问者的访问持续时间输出到每个检查点(它可以正常工作):

match (vr: Visitor {MAC: '00:0a:95:9d:68:16'})-->(v1: Visit)-->(cp1: CheckPoint)
optional match (vr: Visitor {MAC: '00:0a:95:9d:68:16'})-->(v2: Visit)-->(cp2: CheckPoint)
where v2.EnterTime > v1.EnterTime
return cp1.CheckPointId, v1.EnterTime, min((v2.EnterTime - v1.EnterTime) / 60000) as visit_duration
order by v1.EnterTime;

但是当我试图平均访问持续时间时:

match (vr: Visitor {MAC: '00:0a:95:9d:68:16'})-->(v1: Visit)-->(cp1: CheckPoint)
optional match (vr: Visitor {MAC: '00:0a:95:9d:68:16'})-->(v2: Visit)-->(cp2: CheckPoint)
where v2.EnterTime > v1.EnterTime
return avg(min((v2.EnterTime - v1.EnterTime) / 60000)) as avg_visit_duration;

它返回一条错误消息:

Error occurred: Can't use aggregate functions inside of aggregate functions.

可能我需要使用WITH子句,但到目前为止,我一直无法使用WITH子句编写查询,这会给出正确的结果(110分钟)。

有什么想法吗?非常感谢您的帮助!谢谢!

2 个答案:

答案 0 :(得分:3)

如果需要传递其他聚合函数的聚合函数的结果,请通过WITH进行。像这样:

match (vr: Visitor {MAC: '00:0a:95:9d:68:16'})-->(v1: Visit)-->(cp1: CheckPoint)
optional match (vr)-->(v2: Visit)-->(cp2: CheckPoint)
where v2.EnterTime > v1.EnterTime
with cp1.CheckPointId as CheckPointId, 
     v1.EnterTime as EnterTime, 
     min((v2.EnterTime - v1.EnterTime) / 60000) as visit_duration
return sum(visit_duration)

答案 1 :(得分:2)

stdob - 答案很棒。这是另一种解决方案。这个查询有点过于复杂,但可能对您的其他查询有用:

MATCH (vr:Visitor {MAC: '00:0a:95:9d:68:16'})-->(v:Visit)-->(:CheckPoint)
WITH vr, v
ORDER BY v.EnterTime
WITH vr, collect(v.EnterTime / 60000) AS visitTimes
WITH vr, visitTimes, range(0, length(visitTimes) - 2) AS indices
WITH vr, reduce(acc = [], i in indices | acc +  [visitTimes[i+1] - visitTimes[i]]) AS timeDifferences
UNWIND timeDifferences AS timeDifference
RETURN vr, sum(timeDifference)