2017-04-01 21 views
2

皆さん!特定の瞬間に多数のチェックポイントにアクセスした訪問者に関する情報を含むNeo4jデータベースがあります。訪問者、訪問者、およびチェックポイントは、ノードとして表されます。Neo4j - 集計関数内で集計関数を使用できません

各訪問者は、デバイスのMACアドレスで識別され、各チェックポイントには一意のIDが割り当てられます。

各訪問ノードには、特定のMACアドレスを持つ訪問者がそれぞれのチェックポイントの近くに最初に気づいたときの時刻(1970年以降のミリ秒数)であるEnterTimeプロパティが含まれています。

注:訪問の継続時間は、次の訪問のEnterTimeとこの訪問のEnterTimeの差として計算する必要があります。

私の目標は、例えば、訪問に関するいくつかの統計を見つけることです 1)特定の訪問者の訪問の平均時間、 2)特定の店舗への訪問の平均時間、 3)最も人気のある店舗(訪問 4の最長合計時間と店舗IE)で最も人気のある店舗(すなわち訪問の最長の平均時間と店舗)など

データベースは、このサイファー・クエリを使用して作成されます

//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) 

お願いしますeクエリー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 avg(min((v2.EnterTime - v1.EnterTime)/60000)) as avg_visit_duration; 

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; 

をしかし、私は訪問の継続時間を平均化しようとしているとき

それはエラーメッセージを返します。

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

はおそらく、私は、WITH句を使用する必要がありますが、これまでのところ、私は与えるWITH句を使用してクエリを記述することができませんでした正しい結果(110分)。

アイデア?あなたの助けが大いに評価されるでしょう!ありがとう!

答えて

2

別の集計関数の集計関数の結果を渡す必要がある場合は、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) 
+0

ありがとうございます!それは実際に仕事をする! – zavanton

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) 
+0

ありがとう!あなたのクエリーも正しい答えを返します!私はさらなる実験にそれを使用するために全力を尽くします! – zavanton