在 neo4j 中创建数据库需要很长时间
Database creation takes to long in neo4j
更新问题:
我是 neo4j 的新手,我正在尝试创建电影评级数据库。我有一个包含 100.000 个寄存器(2.3 MB)的文件,代表用户对电影进行评分的时间;文件看起来像这样(这个数据集来自 MovieLens):
dataset file
我正在使用 py2neo 并使用以下代码创建了数据库:
data = pd.read_csv('ratings_small.csv')
def create_bipartite_graph(data):
#Indexes creation to perform the queries
graph.run('''
CREATE INDEX user_index IF NOT EXISTS FOR (u:User) ON (u.UserId)
''')
graph.run('''
CREATE INDEX movie_index IF NOT EXISTS FOR (m:Movie) ON (m.MovieId)
''')
actual_user_node = None
for index, row in data.iterrows():
userID = int(row['userId'])
movieID = int(row['movieId'])
rating = row['rating']
date = datetime.fromtimestamp(row['timestamp']).strftime("%m/%d/%Y, %H:%M:%S")
#Creation nodes and relationships
graph.run('''
MERGE(u:User{UserId: $uID})
MERGE(m:Movie{MovieId: $mID})
CREATE (u)-[:RATED_MOVIE{rating: $r, date: $d}]->(m)
''', parameters = {'uID': userID, 'mID': movieID, 'r': rating, 'd': date})
问题出在那个小数据集上,创建图表需要 2 个多小时。对数据库创建时间大大减少有什么建议吗?
使用LOAD CSV
:
这是我在 neo4j 浏览器中执行的查询
EXPLAIN LOAD CSV With HEADERS FROM 'file:///ratings_small.csv' AS line FIELDTERMINATOR ','
MERGE(m:Movie{MovieId: toInteger(line.movieId)})
MERGE(u:User{UserId: toInteger(line.userId)})
CREATE (u)-[:RATED_MOVIE{rating:toFloat(line.rating)}]->(m)
这是个人资料计划:
profile plan
您是从 CSV 文件开始的,对吧?您可以使用 LOAD CSV 将其导入 Neo4j。使用您的 python 代码将 csv 文件放入 Neo4j 导入目录。然后 运行 这个查询 ...
LOAD CSV With HEADERS FROM 'file:///ratings_small.csv' AS line FIELDTERMINATOR ',' MERGE(m:Movie{MovieId: toInteger(line.mID)})
''', parameters = {'mID': toInteger(line.movieID),rating:toFloat(line.rating)})
如果你想一次迭代 5000 行,你可以在开始添加这个
Using periodic commit 5000 ....
这应该 运行 快得多!
每个 graph run
调用不仅表示到服务器的完整往返,而且表示完全独立的事务。像这样工作,在循环的每个循环中进行一次这样的调用,因此效率非常低。
我建议改为查看批量数据操作 API:
https://py2neo.readthedocs.io/en/stable/bulk/index.html
更新问题:
我是 neo4j 的新手,我正在尝试创建电影评级数据库。我有一个包含 100.000 个寄存器(2.3 MB)的文件,代表用户对电影进行评分的时间;文件看起来像这样(这个数据集来自 MovieLens):
dataset file
我正在使用 py2neo 并使用以下代码创建了数据库:
data = pd.read_csv('ratings_small.csv')
def create_bipartite_graph(data):
#Indexes creation to perform the queries
graph.run('''
CREATE INDEX user_index IF NOT EXISTS FOR (u:User) ON (u.UserId)
''')
graph.run('''
CREATE INDEX movie_index IF NOT EXISTS FOR (m:Movie) ON (m.MovieId)
''')
actual_user_node = None
for index, row in data.iterrows():
userID = int(row['userId'])
movieID = int(row['movieId'])
rating = row['rating']
date = datetime.fromtimestamp(row['timestamp']).strftime("%m/%d/%Y, %H:%M:%S")
#Creation nodes and relationships
graph.run('''
MERGE(u:User{UserId: $uID})
MERGE(m:Movie{MovieId: $mID})
CREATE (u)-[:RATED_MOVIE{rating: $r, date: $d}]->(m)
''', parameters = {'uID': userID, 'mID': movieID, 'r': rating, 'd': date})
问题出在那个小数据集上,创建图表需要 2 个多小时。对数据库创建时间大大减少有什么建议吗?
使用LOAD CSV
:
这是我在 neo4j 浏览器中执行的查询
EXPLAIN LOAD CSV With HEADERS FROM 'file:///ratings_small.csv' AS line FIELDTERMINATOR ','
MERGE(m:Movie{MovieId: toInteger(line.movieId)})
MERGE(u:User{UserId: toInteger(line.userId)})
CREATE (u)-[:RATED_MOVIE{rating:toFloat(line.rating)}]->(m)
这是个人资料计划: profile plan
您是从 CSV 文件开始的,对吧?您可以使用 LOAD CSV 将其导入 Neo4j。使用您的 python 代码将 csv 文件放入 Neo4j 导入目录。然后 运行 这个查询 ...
LOAD CSV With HEADERS FROM 'file:///ratings_small.csv' AS line FIELDTERMINATOR ',' MERGE(m:Movie{MovieId: toInteger(line.mID)})
''', parameters = {'mID': toInteger(line.movieID),rating:toFloat(line.rating)})
如果你想一次迭代 5000 行,你可以在开始添加这个
Using periodic commit 5000 ....
这应该 运行 快得多!
每个 graph run
调用不仅表示到服务器的完整往返,而且表示完全独立的事务。像这样工作,在循环的每个循环中进行一次这样的调用,因此效率非常低。
我建议改为查看批量数据操作 API: https://py2neo.readthedocs.io/en/stable/bulk/index.html