2013-10-25 51 views
2

我正在構建一個應用程序,讓我的用戶可以管理字典。一個功能是上傳文件以初始化或更新字典的內容。Neo4j:插入7k節點很慢(Spring Data Neo4j/SpringRestGraphDatabase)

我關注的一部分結構是Dictionary -[:CONTAINS]->Word。 從一個空數據庫(Neo4j 1.9.4,但也試過2.0.0M5)開始,通過Spring Data Neo4j 2.3.1在分佈式環境中訪問(因此使用SpringRestGraphDatabase,但使用localhost進行測試),我試圖加載7k 1字典中的單詞。然而,我不能在少於8/9分鐘的時間內完成核心i7,8Gb RAM和SSD驅動器(ulimit提高到40000)的Linux。

我讀過很多關於使用REST加載/插入性能的帖子,我嘗試應用我發現的建議,但沒有更好的運氣。由於我的應用程序限制,BatchInserter工具對我來說似乎不是一個好選擇。

我希望能在幾秒鐘內而不是幾分鐘內加載10k個節點嗎?

這裏是我想出了一個代碼,經過我的所有讀數:

Map<String, Object> dicProps = new HashMap<String, Object>(); 
dicProps.put("locale", locale); 
dicProps.put("category", category); 
Dictionary dictionary = template.createNodeAs(Dictionary.class, dicProps); 
Map<String, Object> wordProps = new HashMap<String, Object>(); 
Set<Word> words = readFile(filename); 
for (Word gw : words) { 
    wordProps.put("txt", gw.getTxt()); 
    Word w = template.createNodeAs(Word.class, wordProps); 
    template.createRelationshipBetween(dictionary, w, Contains.class, "CONTAINS", true); 
} 
+0

如果您創建所有實體分離並將它們全部保存,會發生什麼情況最後呢?在你的字典類中有一個'Set '適當的註釋,用'new'創建字典和單詞,如普通對象,而不是模板,將所有單詞添加到字典集'字典。addWord(word)',只有在最後你用'template.save(dict)'來堅持這一切。有什麼區別? – jjaderberg

回答

0

試試下面

  1. USW本地Neo4j的API,而不是彈簧數據的Neo4j在執行批處理操作。
  2. 提交分批即可以是用於每500個字

注意:有由SDN這將使用本機方法時,會丟失某些添加屬性()。

+0

謝謝,我會嘗試一下(如果使用原生Neo4j API,則意味着直接調用Rest API)。 –

+0

@AlainB。 Neo4j提供Java API(與REST API不同),可用於與EMBEDDED Neo4j DB交談。使用嵌入式Neo4j時性能更高 –

+0

我嘗試過嵌入模式,性能非常好,不幸的是,在我的問題中提到我不能使用嵌入模式,因爲我有幾個應用程序服務器需要與Neo4j服務器交談。 –

1

我通過創建一些CSV文件解決了這個問題,然後從Neo4j中讀取它。這是需要做出這樣的步驟:

  1. 寫一些類來創建CSV文件,得到它的輸入數據和基礎(也可以是每個節點類型的一個文件,甚至您可以創建一個用於構建文件關係)。

  2. 在我的情況下,我也創建了servlet,允許Neo4j通過HTTP讀取該文件。

  3. 創建適當的Cypher語句,允許讀取和解析該CSV文件。還有一些樣品,其中我使用(如果你使用Spring的數據還記得有關標籤):

    • 簡單:

      load csv with headers from {fileUrl} as line 
          merge (:UserProfile:_UserProfile {email: line.email}) 
      
    • 更加複雜:

      load csv with headers from {fileUrl} as line 
          match (c:Calendar {calendarId: line.calendarId}) 
          merge (a:Activity:_Activity {eventId: line.eventId}) 
      on create set a.eventSummary = line.eventSummary, 
          a.eventDescription = line.eventDescription, 
          a.eventStartDateTime = toInt(line.eventStartDateTime), 
          a.eventEndDateTime = toInt(line.eventEndDateTime), 
          a.eventCreated = toInt(line.eventCreated), 
          a.recurringId = line.recurringId 
      merge (a)-[r:EXPORTED_FROM]->c 
      return count(r)