2016-12-11 45 views
0

我有一個帶有以下列的事件日誌的CSV:EventType,UserId,RecordId(自動遞增的序列號)。我想導入Neo4j併爲每個EventType(大約100個獨特類型)構建一個節點,然後使用關係分析路徑。爲了建立關係,我需要匹配所有的原始事件,並找到在路徑中的「下一個」事件,這意味着我需要與事件有相同UserId和明年RecordId比當前RecordIdnext RecordId > current RecordId)大相匹配。 在Cypher中執行此操作的有效方法是什麼?不知何故,我想出了涉及笛卡爾產品的查詢,這些查詢非常緩慢。根據事件序列創建關係

回答

0

我想你不能避免笛卡爾乘積在這種情況下。但是,您可以

  1. 使它們儘可能小。
  2. 使用索引來提高查詢的速度。

除了使用EventType爲節點標籤(「獨特型」),我強烈建議使用一個額外的Event標籤的所有事件,以便您可以索引userId值和recordId值。

CREATE INDEX ON :Event(recordId) 
CREATE INDEX ON :Event(userId) 

我創建了一個小示例數據集:

CREATE 
    (e1:Event:Skating {userId: 1, recordId: 1}), 
    (e2:Event:Hiking {userId: 1, recordId: 2}), 
    (e3:Event:Mountaineering {userId: 1, recordId: 3}) 

獲得下一個recordId,你需要滿足的是nextRecordId > currentRecordId,也是nextRecordId必須是最小的一個(爲recordId來自一個自動遞增序列)。我們比連接使用MERGE兩個事件(CREATE也適用,但使用MERGE可以確保我們避免創建重複邊緣)。這給出以下查詢:

MATCH (a:Event), (b:Event) 
WHERE a.userId = b.userId 
    AND a.recordId < b.recordId 
WITH a, min(b.recordId) AS bRecordId 
MATCH (b {recordId: bRecordId}) 
MERGE (a)-[:NEXT]->(b) 

此查詢爲所有用戶標識創建笛卡爾產品。只要用戶不參與數百個活動,笛卡爾產品的規模就不應該變大。需要注意的是,第一MATCH使用這兩個指數(userIdrecordId),而第二MATCH使用上recordId索引。

+0

它運行速度非常慢。 理論上講,如果我把所有的事件放在一個平衡樹中,可以用nlogn的複雜度來完成。如果我爲每個用戶創建一個平衡樹的散列表並通過recordid命令樹節點。 –

+0

如果你能寫一些代碼(如Java中)添加的關係,你可以實現一個解決方案,快哩 - 如你所說,你可以使用額外的數據結構,如哈希表和樹木。 –