2014-08-29 36 views
2

我目前正在探索圖表數據庫的潛力,在我的行業中的一些流程。 一個星期前我開始使用Neo4Jclient,所以我低於標準初學者:-)使用neo4jclient的性能問題

我對Neo4J很興奮,但我面臨着巨大的表演問題,我需要幫助。

我的項目的第一步是從現有的文本文件填充Neo4j。 這些文件是由使用一個簡單的模式格式化行:

StringID=StringLabel(String1,String2,...,StringN); 

對於爲例,如果我認爲以下行:

#126=TYPE1(#80,#125); 

我想創建一個標籤「TYPE1」一個節點, 2個性能: 1)使用的ObjectID的唯一ID:在上面的例子中 2)「#126」含有以備將來使用的所有參數的字符串:在上面的例子中「#80,#125」

我必須考慮到我將處理多個前向引用,如在下面的爲例:

#153=TYPE22('0BTBFw6f90Nfh9rP1dl_3P',#144,#6289,$); 

的線定義所述節點與的StringID「#6289」將在後面的文件中解析。

因此,要解決我的文件導入的問題,我已經定義了以下類:

public class myEntity 
{ 
    public string propID { get; set; } 
    public string propATTR { get; set; } 

    public myEntity() 
    { 
    } 
} 

而且由於轉發在我的文本文件的引用(與毫無疑問,我可憐的Neo4j的知識...) 我已經決定在3個步驟的工作:

一環,我解壓,從我的文件,strLABEL,strID和strATTRIBUTES,解析每一行 後來我加一個Neo4j的節點使用下面的每一行代碼:

strLabel = "(entity:" + strLABEL + " { propID: {newEntity}.propID })"; 
graphClient.Cypher 
    .Merge(strLabel) 
    .OnCreate() 
    .Set("entity = {newEntity}") 
    .WithParams(new { 
     newEntity = new { 
      propID = strID, 
      propATTR = strATTRIBUTES 
     } 
    }) 
    .ExecuteWithoutResults(); 

然後我匹配的Neo4j創建使用以下代碼中的所有節點:

var queryNode = graphClient.Cypher 
    .Match("(nodes)") 
    .Return(nodes => new { 
     NodeEntity = nodes.As<myEntity>(), 
     Labels = nodes.Labels() 
    } 
); 

而且所有節點上終於我環,分裂propATTR屬性爲每個節點和添加一個關係對於每個使用以下代碼propATTR的ObjectID發現:

graphClient.Cypher 
    .Match("(myEnt1)", "(myEnt2)") 
    .Where((myEntity myEnt1) => myEnt1.propID == strID) 
    .AndWhere((myEntity myEnt2) => myEnt2.propID == matchAttr) 
    .CreateUnique("myEnt1-[:INTOUCHWITH]->myEnt2") 
    .ExecuteWithoutResults(); 

當我探討使用Cypher支架使用的代碼填入數據庫,得到的節點和關係是正確的和Neo4j的執行速度是非常快的我測試過任何疑問。 這是非常令人印象深刻的,我確信Neo4j在我的行業有一個巨大的潛力。

但我的大問題,今天來填充數據庫(我的配置:win8的64位,32Go RAM,SSD,英特爾酷睿i7-3840QM 2.8GHz的):需要時間

對於一個小的測試案例(6400線) 它花了我13秒創造6373個節點,和94S更創造7800個關係

一個真正的測試案例(40000行) 它花了我496s創造38898個節點,並3701s更創造出89532個關係(是:超過一個小時!)

我毫不懷疑這種糟糕的表現直接來自於我的不良neo4jclient知識。

如果社區能夠就如何解決瓶頸問題給出建議,對我來說將是一個巨大的幫助。

非常感謝您的幫助。

問候 最大

+0

您多久導入一次數據?通常這是一次性的(或者很少的時間),而且在考慮性能時並不是人們通常關注的內容。如果您以3.7K秒的速度導入89K關係,是不是差不多25 /秒?而且你在導入時每秒創建超過75個節點,對吧?這真的很慢嗎?你真的需要經常重複這個過程嗎?另一件事是,Neo4j有一個內置的導入器(使用CSV)。你有沒有嘗試過,而不是通過代碼進行節點導入?順便說一句:您的匹配代碼似乎不使用標籤過濾。 – 2014-08-31 15:51:15

+1

首先,非常感謝您的回答。根據產品生命週期步驟的不同,導入數據可以是一天數次(設計階段)或一次性步驟(移交後的操作階段)。在當前的代碼中,我使用節點標籤(並且可能有近200個不同的標籤)對它們進行分類:這是一個不錯的選擇,還是應該向每個節點添加屬性字符串類別?將嘗試使用CSV導入,並通知結果。最後,我在導入階段過濾時沒有使用標籤,因爲我需要匹配所有節點以在它們之間添加rels。 – 2014-09-03 04:43:41

回答

0

雖然我沒有在我的腦海確切的語法寫下你的,我建議你看一下,當你開始讀他們的分裂值propATTR,並直接將它們存儲作爲Neo4j中的數組/集合。這將有助於您在Neo4j中批量創建關係,而不是從外部迭代節點並執行如此多的連續事務。

後期可能類似於:

MATCH (myEnt1),(myEnt2) WHERE myEnt1.propID IN myEnt2.propATTR 
CREATE UNIQUE (myEnt1)-[:INTOUCHWITH]->(myEnt2) 

對不起我的暗號是有點生疏,但關鍵是要儘量充分轉移負荷到Neo4j的引擎,而不是不斷往返在您的應用程序邏輯和Neo4j服務器之間。我建議,這可能是這些往返行程會影響你的業績,而不是每一筆交易中涉及的個別工作,所以儘量減少交易數量是一條路。