Neo4j加载CSV应用程序线程被阻止

Neo4j加载CSV应用程序线程被阻止,neo4j,graphenedb,Neo4j,Graphenedb,我正在尝试使用neo4j中的LOAD CSV命令从CSV文件导入大约500000行数据 csv中的数据组织如下: Artists | Feature1 | Feature2 | Feature3 每个栏目都有音乐艺术家的名字,他们中的大多数人在一个栏目中出现过不止一次。如果某个艺术家的名字出现在任何列中,我希望该艺术家有一个节点。如果该艺术家的名字在一列和/或多个列中出现多次,我希望该艺术家只有一个节点 对于每一位艺术家,我想记录他们的特征以及他们为谁而特征

我正在尝试使用neo4j中的
LOAD CSV
命令从CSV文件导入大约500000行数据

csv中的数据组织如下:

Artists    |    Feature1    |    Feature2    |    Feature3
每个栏目都有音乐艺术家的名字,他们中的大多数人在一个栏目中出现过不止一次。如果某个艺术家的名字出现在任何列中,我希望该艺术家有一个节点。如果该艺术家的名字在一列和/或多个列中出现多次,我希望该艺术家只有一个节点

对于每一位艺术家,我想记录他们的特征以及他们为谁而特征。csv的每一行代表一首歌。对于艺术家制作的每首歌曲(csv的每一行),我想在
artist
列中的艺术家与
Features1/2/3
列中的艺术家之间添加一个
FEATURES
关系

以下是我正在使用的代码:

CREATE CONSTRAINT ON (a:Artist) ASSERT a.artistName IS UNIQUE;

USING PERIODIC COMMIT 50
LOAD CSV WITH HEADERS from 'https://aws.bigfile.csv' as line
MERGE (artist:Artist {artistName: line.Artist})
MERGE (feature1:Artist {artistName: line.Feature1})
MERGE (feature2:Artist {artistName: line.Feature2})
MERGE (feature3:Artist {artistName: line.Feature3})

MERGE (artist)-[f1:FEATURES]->(feature1) 
ON CREATE SET f1.strength = 1
ON MATCH SET f1.strength = f1.strength + 1

MERGE (artist)-[f2:FEATURES]->(feature2) 
ON CREATE SET f2.strength = 1
ON MATCH SET f2.strength = f2.strength + 1

MERGE (artist)-[f3:FEATURES]->(feature3) 
ON CREATE SET f3.strength = 1
ON MATCH SET f3.strength = f3.strength + 1
期望的行为:第一次出现的具有其他艺术家特征的人创建了
特征
关系,并且应该将
特征
关系的
强度
属性设置为1。对于每个后续事件,“强度”特性将增加1。因此,经常以艺术家B为主角的艺术家A应该具有类似于
(A)-[:features{strength:AHighNumber]->(B)

在这种情况下,关系是方向性的,方向性很重要(以B为特征的A与以A为特征的B不同)

应该有超过10000个不同的艺术家,因此节点,但大约2000个节点,我开始与系统超时问题

我在日志中收到了以下信息:

2017-12-30 10:54:04.268+0000 WARN [o.n.k.i.c.MonitorGc] GC Monitor: Application threads blocked for 467ms.
是否有其他信息对确定问题有用?是否知道如何重新构造代码以避免此问题?非常感谢所有帮助。谢谢!

我已经找到了一个(中间)解决方案,它不会直接解决上面的内存问题,但仍然有效

以前,我尝试从原始文件创建艺术家节点,合并它们,以便每个艺术家都有一个且只有一个节点。我怀疑创建/合并节点的成本越来越高,因为对于文件的每一行,cypher基本上必须查看所有现有节点,以查看是否为t创建新节点帽排

相反,我编写了一些Python代码来获取唯一的值(艺术家名称)对于每个列,将它们合并到一个长列表中,然后再次从该列表中获取唯一值,以筛选出出现在多个列中的重复艺术家。然后,我将其写入一个包含一列艺术家的文件。我使用这个短得多的文件创建所有艺术家节点。代码:

data = pd.read_csv('artists-full.csv', encoding = 'latin1')
columns = ['Artist', 'Feature1', 'Feature2', 'Feature3']
df = pd.DataFrame(data, columns=columns)

# Get an array of strings for each column. Clean out repeats
artists_set1 = df.loc[:, 'Artist'].unique().tolist()
artists_set2 = df.loc[:, 'Feature1'].unique().tolist()
artists_set3 = df.loc[:, 'Feature2'].unique().tolist()
artists_set4 = df.loc[:, 'Feature3'].unique().tolist()

# Combine the artists from different columns
artists_list = [artists_set1, artists_set2, artists_set3, artists_set4]
flat_artists_list = [item for sublist in artists_list for item in sublist]
# Get rid of duplicates by creating a set
artists_set = set(flat_artists_list)
# Turn the set back into a list
artists = list(artists_set)
print(len(artists))

# Write the list to csv
with open ('artists.csv', 'w', encoding='utf-8') as f:
    for artist in artists:
        f.write(str(artist) + '\n')
在此基础上,我使用原始文件和以下密码创建了艺术家之间的关系:

CREATE CONSTRAINT ON (a:Artist) ASSERT a.artistName IS UNIQUE;
MERGE (artist)-[f1:FEATURES]->(feature1) 
ON CREATE SET f1.strength = 1
ON MATCH SET f1.strength = f1.strength + 1

MERGE (artist)-[f2:FEATURES]->(feature2) 
ON CREATE SET f2.strength = 1
ON MATCH SET f2.strength = f2.strength + 1

MERGE (artist)-[f3:FEATURES]->(feature3) 
ON CREATE SET f3.strength = 1
ON MATCH SET f3.strength = f3.strength + 1
如果将查询粘贴到浏览器中(不运行它,只粘贴它),则会在旁边显示一条警告,当扩展时,警告内容如下:

此查询的执行计划包含渴望运算符,该运算符 强制所有依赖数据在之前在主内存中具体化 诉讼程序 在查询中使用LOAD CSV和大数据集,其中 执行计划包含可能会消耗 内存太多,可能无法正常工作。请参阅Neo4j手册 有关如何操作的更多信息和提示,请输入“急切”操作符 问题是可以避免的

这就解释了为什么会出现性能问题……它有效地取消了任何定期提交的使用

当您在同一个节点标签上进行多个合并时,您可以在查询计划中获得即时操作。解决此类问题的一般方法是通过CSV中的单个变量将节点合并一次:

USING PERIODIC COMMIT 50
LOAD CSV WITH HEADERS from 'https://aws.bigfile.csv' as line
MERGE (artist:Artist {artistName: line.Artist})
如果CSV中的
line.Artist
具有所有可能的美工人员,则单次传递应该有效。但是,如果
line.Feature1
中有其他美工人员(以及其他)不在
line.Artist
,则您需要依次对每个美工人员执行另一次传递,直到加载所有节点(您还可以将定期提交推高到5000到10000左右)

请注意,将同一关系类型的多个合并到多个节点也有助于进行急切操作。您应该真正了解是否可以以不同的格式获取CSV。您不需要所有额外的列,
line.Artist
line.Feature
应该足够了,然后您将拥有多行它具有相同的艺术家和不同的功能,您不会被急切的操作所困扰

您的备选方案是(在导入所有节点后)分3次执行查询,以避免急切操作并允许使用定期提交:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS from 'https://aws.bigfile.csv' as line
match (artist:Artist {artistName: line.Artist})
match (feature:Artist {artistName: line.Feature1})

MERGE (artist)-[f:FEATURES]->(feature1) 
ON CREATE SET f.strength = 1
ON MATCH SET f.strength = f.strength + 1
然后对
line.Feature2
line.Feature3
重复上述操作