2015-09-01 20 views
0

我有一個非常簡單的密碼,這給我一個糟糕的表現。 我有約。 200萬用戶和60種圖書類別,用戶與類別之間的關係約爲2800萬。 當我這樣做暗號:Neo4j cyper性能簡單匹配

MATCH (u:User)-[read:READ]->(bc:BookCategory) 
WHERE read.timestamp >= timestamp() - (1000*60*60*24*30) 
RETURN distinct(bc.id); 

它返回我2內8.5K行 - 2.5(第一次)分鐘

當我這樣做暗號:

MATCH (u:User)-[read:READ]->(bc:BookCategory) 
WHERE read.timestamp >= timestamp() - (1000*60*60*24*30) 
RETURN u.id, u.email, read.timestamp; 

它返回55K 3到6(第一次)分鐘內的行。

我已經有用戶ID和電子郵件的索引,但我仍然認爲這種性能是不可接受的。任何想法我怎麼能改善這一點?

回答

0

你能解釋一下你的模型嗎?

書籍和「閱讀」 - 它在哪裏?

Afaik所有你想知道的,最近讀過哪些書類(上個月)?

您可以創建第二種類型的關係,該關係RECENTLY_READ由於批處理作業超過30天而過期(被刪除)。 (這可以是創建和刪除這些關係的兩個簡單的密碼語句)。

WITH (1000*60*60*24*30) as month 
MATCH (a:User)-[read:READ]->(b:BookCategory) 
WHERE read.timestamp >= timestamp() - month 
MERGE (a)-[rr:RECENTLY_READ]->(b) 
WHERE coalesce(rr.timestamp,0) < read.timestamp 
SET rr.timestamp = read.timestamp; 

WITH (1000*60*60*24*30) as month 
MATCH (a:User)-[rr:RECENTLY_READ]->(b:BookCategory) 
WHERE rr.timestamp < timestamp() - month 
DELETE rr; 

還有另一種方式來實現你正是想在這裏做什麼,但它不幸的是沒有可能的Cypher支架。

根據您的閱讀關係,timestamp上的關係索引可以在Neo4j的Java API中運行Lucene-NumericRangeQuery。

但我不會推薦走這條路。

+1

HI邁克爾,我第一次導入(書)和(BookCategory)作爲Neo4j中的節點,之後,基於歷史的csv文件,我創建了名爲[:READ]的屬性時間戳的關係,該關係將記錄何時該書讀。你是對的,我想知道哪些書類最近被閱讀過,這是我選擇類別的標準。最初,我試圖避免批量作業,因此不需要額外的工作量/維護。但是,如果這是唯一的方法(並且我認爲索引不會有幫助),那麼別無選擇。 – Dee

+0

我真的不想在Lucene上創建索引,以便維護。如果我運行一個批處理作業並創建一個名爲'RECENTLY_READ'的屬性,我是否有必要說我還需要對它進行索引? – Dee

+0

HI邁克爾,我測試了你的密碼,但有一個錯誤。我認爲WHERE子句不能與MERGE一起使用。 – Dee

1

首先,你可以profile你的查詢,找到底下發生了什麼。

當前看起來像該查詢掃描數據庫中的所有節點以完成查詢。

原因:

  • 只爲「=」操作(或「IN」)
  • 要完成查詢Neo4j的支持指標,它遍歷所有節點,逐一檢查每個節點是否具有有效時間戳

有沒有簡單的方法來處理這個問題。 您應該研究創建適當的圖結構,以更有效地處理特定於時間的查詢。如何在圖形數據庫中表示時間有幾種方法。

您可以看看graphaware/neo4j-timetree庫。

+0

謝謝FylmTM,我想它正在掃描數據庫中的所有節點來完成查詢,因爲我需要找出符合條件的日期。我試圖避免時間特定的查詢,看看我能否以更簡單的方式實現我所需要的。 – Dee