2017-04-02 36 views
1

大家好!我有一個Neo4j數據庫,其中包含關於在特定時刻訪問多個檢查點的訪問者的信息。訪問者,訪問和檢查點以節點表示。Neo4j密碼查詢與聚合函數返回不完全結果

每個訪問者都由他/她的設備MAC地址標識,每個檢查點都有一個唯一的ID。

每個訪問節點都包含一個EnterTime屬性,該屬性是具有某個特定MAC地址的訪問者首先在相應檢查點附近被發現時的時間(1970年以來的毫秒數)。

注意:訪問的持續時間應計算爲下一次訪問的EnterTime與此訪問的EnterTime之間的時間差。每個檢查點可能會被訪問​​多次。

數據庫與此CYPHER查詢創建:

//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爲id = 1的檢查點未考慮在內。但這是我的猜測。

我的查詢有什麼問題?如何改進以返回正確的結果?

您的幫助將非常感謝!謝謝!

回答

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; 

with聲明中vr。 Cypher小組按您在with聲明中輸入的所有值進行分組。您的代碼無法工作的原因是因爲針對訪問者1和2的檢查點1的v1.EnterTime是相同的。因爲with聲明中只有EnterTimeCheckpointID,所以密碼按EnterTime分組,因爲您擁有min(v2.EnterTime - v1.EnterTime),它只佔用較小的一個,但不使用兩者。現在我們在with語句中引入Visitor,它也將由訪問者分組,這解決了我們的問題,如果兩個人同時啓動同一個檢查點。

希望這會有所幫助

+0

謝謝!它解決了這個問題!我非常感謝你的幫助!希望對於其他與Neo4j和cypher一起努力的人來說,這將是有用的。 – zavanton