大家好!我有一个Neo4j数据库,其中包含有关在特定时刻访问多个检查点的访问者的信息。访问者,访问和检查点表示为节点。
每个访问者都由他/她的设备MAC地址标识,每个检查点都有唯一的ID。
每个访问节点都包含一个EnterTime属性,该属性是在相应检查点附近首次发现具有某些特定MAC地址的访问者时的时间(自1970年以来的毫秒数)。
注意:访问的持续时间应计算为下次访问的EnterTime与此次访问的EnterTime之间的差异。每个检查点可能会被访问多次。
使用此密码查询创建数据库:
//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)
我正在编写一个密码查询来查找每个检查点的总访问时间。 我正在尝试这个:
match (vr: Visitor)-->(v1: Visit)-->(cp1: CheckPoint),
(vr)-->(v2: Visit)-->()
where v2.EnterTime > v1.EnterTime
with cp1.CheckPointId as CheckPointId,
v1.EnterTime as EnterTime,
min((v2.EnterTime - v1.EnterTime) / 60000) as visit_duration
return CheckPointId, sum(visit_duration) as total_visit_duration
order by CheckPointId;
结果应为:
cp1 - 48 min
cp2 – 40 min
cp3 – 65 min
cp4 – 115 min
cp5 – 10 min
但是我的查询返回了错误的结果:
cp1 - 23 min
cp2 – 40 min
cp3 – 65 min
cp4 – 115 min
cp5 – 10 min
显然,错误是访问者(mac == 00:0a:95:9d:68:17)访问id == 1的检查点的长度没有被考虑在内。但这是我的猜测。
我的查询有什么问题?如何改进以返回正确的结果?
非常感谢您的帮助!谢谢!
答案 0 :(得分:2)
我认为你在寻找的是:
match ()<--(v2:Visit)<--(vr: Visitor)-->(v1: Visit)-->(cp1: CheckPoint)
where v2.EnterTime > v1.EnterTime
with vr,
cp1.CheckPointId as CheckPointId,
v1.EnterTime as EnterTime,
min((v2.EnterTime - v1.EnterTime) / 60000) as visit_duration
return CheckPointId, sum(visit_duration) as total_visit_duration
order by CheckPointId;
我在vr
声明中添加了with
。 Cypher根据您在with
语句中输入的所有值进行分组。您的代码无法工作的原因是因为访问者1和2的检查点1的v1.EnterTime
是相同的。因为EnterTime
语句中只有CheckpointID
和with
,所以cypher按EnterTime
分组,所以因为你有min(v2.EnterTime - v1.EnterTime)
它只是拿了较小的一个并且做了Visitor
不要同时使用。现在我们在with
语句中引入soundPlayer = new Audio(soundName).play();
,如果两个人同时启动相同的检查点,它也将按访问者分组,这解决了我们的问题。
希望这有帮助