簡體   English   中英

使用Py2neo將大型xml文件導入Neo4j

[英]Importing a large xml file to Neo4j with Py2neo

我在導入一個包含36196662行的非常大的XML文件時遇到問題。 我正在嘗試用Py2neo我的xml文件創建這個XML文件的Neo4j圖形數據庫 ,如下所示:

http://imgur.com/pLylHeG

和我的python代碼將xml數據導入Neo4j是這樣的:

from xml.dom import minidom
from py2neo import Graph, Node, Relationship, authenticate
from py2neo.packages.httpstream import http
http.socket_timeout = 9999
import codecs

authenticate("localhost:7474", "neo4j", "******")

graph = Graph("http://localhost:7474/db/data/")

xml_file = codecs.open("User_profilesL2T1.xml","r", encoding="latin-1")

xml_doc = minidom.parseString (codecs.encode (xml_file.read(), "utf-8"))

#xml_doc = minidom.parse(xml_file)
persons = xml_doc.getElementsByTagName('user')
label1 = "USER"

# Adding Nodes
for person in persons:


    if person.getElementsByTagName("id")[0].firstChild:
       Id_User=person.getElementsByTagName("id")[0].firstChild.data
    else: 
       Name="NO ID"
    print ("******************************USER***************************************")
    print(Id_User)



    print ("*************************")
    if person.getElementsByTagName("name")[0].firstChild:
       Name=person.getElementsByTagName("name")[0].firstChild.data
    else: 
       Name="NO NAME"   
   # print("Name :",Name)


    print ("*************************")
    if person.getElementsByTagName("screen_name")[0].firstChild:
       Screen_name=person.getElementsByTagName("screen_name")[0].firstChild.data
    else: 
       Screen_name="NO SCREEN_NAME" 
  #   print("Screen Name :",Screen_name)

    print ("*************************") 
    if person.getElementsByTagName("location")[0].firstChild:
       Location=person.getElementsByTagName("location")[0].firstChild.data
    else: 
       Location="NO Location"   
 #    print("Location :",Location)


    print ("*************************")
    if person.getElementsByTagName("description")[0].firstChild:
       Description=person.getElementsByTagName("description")[0].firstChild.data
    else: 
       Description="NO description" 
  #   print("Description :",Description)


    print ("*************************") 
    if person.getElementsByTagName("profile_image_url")[0].firstChild:
       Profile_image_url=person.getElementsByTagName("profile_image_url")[0].firstChild.data
    else: 
       Profile_image_url="NO profile_image_url" 
   # print("Profile_image_url :",Profile_image_url)

    print ("*************************")
    if person.getElementsByTagName("friends_count")[0].firstChild:
       Friends_count=person.getElementsByTagName("friends_count")[0].firstChild.data
    else: 
       Friends_count="NO friends_count" 
 #    print("Friends_count :",Friends_count)


    print ("*************************")
    if person.getElementsByTagName("url")[0].firstChild:
       URL=person.getElementsByTagName("url")[0].firstChild.data
    else: 
       URL="NO URL" 
  #   print("URL :",URL)






    node1 = Node(label1,ID_USER=Id_User,NAME=Name,SCREEN_NAME=Screen_name,LOCATION=Location,DESCRIPTION=Description,Profile_Image_Url=Profile_image_url,Friends_Count=Friends_count,URL=URL)
    graph.merge(node1)  

我的問題是當我運行代碼時,需要很長時間才能導入這個文件差不多一個星期才能做到這一點,所以如果有人能幫助我更快地導入數據,那將非常感激。

注意:我的筆記本配置是:4Gb RAM,500Gb硬盤,i5

我認為你應該使用一個流解析器,否則它甚至可能在python一側溢出內存。

另外,我建議在Neo4j中進行交易,每次交易批量為10k到100k。

不要存儲"NO xxxx"字段,只要將它們關閉它只是浪費空間和精力。

我不知道merge(node)是如何工作的。 我建議在:User(userId)上創建一個唯一約束,並使用如下的密碼查詢:

UNWIND {data} as row
MERGE (u:User {userId: row.userId}) ON CREATE SET u += {row}

其中{data}參數是具有屬性的字典列表(例如10k條目)。

如果要將數據導入新數據庫,可能需要嘗試導入工具: https//neo4j.com/docs/operations-manual/current/#import-tool

在這種情況下,您應該像現在一樣解析XML文件,而不是使用py2neo將數據插入Neo4j,只需編寫一個CSV文件,然后再調用導入工具。

請參閱下面的可能方法:

import csv
from xml.dom import minidom

def getAttribute(node,attribute,default=None):
    attr = node.getElementsByTagName(attribute)[0]
    return attr.firstChild.data if attr.firstChild else default

xml_doc = minidom.parse(open("users.xml"))
persons = xml_doc.getElementsByTagName('user')

users = []
attrs = ['name','screen_name','location','description','profile_image_url','friends_count','url']

mapping = {'user_id': 'user_id:ID(User)',
           'name': 'name:string',
           'screen_name': 'screen_name:string',
           'location': 'location:string',
           'description': 'description:string',
           'profile_image_url': 'profile_image_url:string',
           'friends_count': 'friends_count:int',
           'url': 'url:string'}

with open('users.csv','w') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=mapping.values())
    writer.writeheader()
    for person in persons:
        user = {mapping[attr]: getAttribute(person, attr) for attr in attrs}
        user[mapping['user_id']] = getAttribute(person, 'id')

        writer.writerow(user)

將xml轉換為csv文件后,運行import-tool:

$ neo4j-import --into neo4j-community-3.0.3/data/databases/users.db --nodes:User users.csv

我想你也想在節點之間建立關系(?)。 您應該閱讀導入工具文檔,並使用csv文件為兩個節點和關系調用import-tool

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM