我有一个csv
文件,其中某些字段是数组类型。字段用,
分隔,数组项用;
分隔。例如:
index, name, friends, neighbors
0,Jim,John;Tim;Fred,Susan;Megan;Cheryl
1,Susan,Jim;John,Megan;Cheryl
2,Sean,,,
其中Jim
有三个朋友John
,Tim
和Fred
,以及三个邻居,Susan
,Megan
和Cheryl
,并且Sean
没有朋友并且没有邻居。
但是,当我使用neo4j
将其读入apoc.load.csv
时,我得到的是带有空字符串(而不是空列表)的列表属性。例如:
CALL apoc.periodic.iterate("
CALL apoc.load.csv('file.csv',
{header:true,sep:',',
mapping:{
friends:{array:true},
neighbors:{array:true}}
})
YIELD map as row RETURN row
","
CREATE (p:Person) SET p = row
",
{batchsize:50000, iterateList:true, parallel:true});
给我一个名称为Person
但名称为Sean
和friends=[ "" ]
的neighbors=[ "" ]
。
我想要的是Sean
具有friends=[]
和neighbors=[]
。
谢谢!
请确保CSV文件标题中没有多余的空格(否则某些属性名称将以空格开头:]
index,name,friends,neighbors
0,Jim,John;Tim;Fred,Susan;Megan;Cheryl
1,Susan,Jim;John,Megan;Cheryl
2,Sean,,,
使用list comprehension帮助消除所有为空字符串的friends
和neighbors
元素:
CALL apoc.periodic.iterate(
"CALL apoc.load.csv(
'file.csv',
{
header:true, sep:',',
mapping: {
friends: {array: true},
neighbors: {array: true}
}
}) YIELD map
RETURN map
",
"CREATE (p:Person)
SET p = map
SET p.friends = [f IN p.friends WHERE f <> '']
SET p.neighbors = [n IN p.neighbors WHERE n <> '']
",
{batchsize:50000, iterateList:true, parallel:true}
);
经过上述更改,此查询:
MATCH (person:Person) RETURN person;
返回此结果:
╒══════════════════════════════════════════════════════════════════════╕
│"person" │
╞══════════════════════════════════════════════════════════════════════╡
│{"name":"Jim","index":"0","neighbors":["Susan","Megan","Cheryl"],"frie│
│nds":["John","Tim","Fred"]} │
├──────────────────────────────────────────────────────────────────────┤
│{"name":"Susan","index":"1","neighbors":["Megan","Cheryl"],"friends":[│
│"Jim","John"]} │
├──────────────────────────────────────────────────────────────────────┤
│{"name":"Sean","index":"2","neighbors":[],"friends":[]} │
└──────────────────────────────────────────────────────────────────────┘
[更新]
此外,如果您的CSV文件不可能包含“空”朋友或邻居子字符串(例如John;;Fred
),那么使用CASE
而不是列表解析的此版本的查询会更有效:
CALL apoc.periodic.iterate(
"CALL apoc.load.csv(
'file.csv',
{
header:true, sep:',',
mapping: {
friends: {array: true},
neighbors: {array: true, arraySep:';'}
}
}) YIELD map
RETURN map
",
"CREATE (p:Person)
SET p = map
SET p.friends = CASE p.friends WHEN [''] THEN [] ELSE p.friends END
SET p.neighbors = CASE p.neighbors WHEN [''] THEN [] ELSE p.neighbors END
",
{batchsize:50000, iterateList:true, parallel:true}
);