使用APOC将CSV导入neo4j时处理空数组类型
我有一个使用APOC将CSV导入neo4j时处理空数组类型,neo4j,cypher,neo4j-apoc,Neo4j,Cypher,Neo4j Apoc,我有一个csv文件,其中一些字段是数组类型。字段用分隔,和数组项用分隔。例如: index, name, friends, neighbors 0,Jim,John;Tim;Fred,Susan;Megan;Cheryl 1,Susan,Jim;John,Megan;Cheryl 2,Sean,,, 其中,吉姆有三个朋友,John,Tim和Fred,还有三个邻居,Susan,Megan和Cheryl,而肖恩既没有朋友也没有邻居 但是,当我使用apoc.load.csv将其读入neo4j时,我得
csv
文件,其中一些字段是数组类型。字段用分隔,
和数组项用分隔代码>。例如:
index, name, friends, neighbors
0,Jim,John;Tim;Fred,Susan;Megan;Cheryl
1,Susan,Jim;John,Megan;Cheryl
2,Sean,,,
其中,吉姆有三个朋友,John
,Tim
和Fred
,还有三个邻居,Susan
,Megan
和Cheryl
,而肖恩既没有朋友也没有邻居
但是,当我使用apoc.load.csv
将其读入neo4j
时,我得到的列表属性中包含空字符串(而不是空列表)。例如:
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
,但名为friends=[“”]
和neights=[“”]
我想要的是肖恩有朋友=[]
和邻居=[]
谢谢大家!
确保CSV文件头中没有多余的空格(否则某些属性名称将以空格开头):
用于帮助消除所有为空字符串的朋友
和邻居
元素:
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}
);
返回此结果:
╒══════════════════════════════════════════════════════════════════════╕
│"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}
);
在您当前的CSV数据中,Jim实际上有3个朋友。已修复!谢谢@cybersamWorks!谢谢你,@cybersam。为了澄清,我们不一定需要添加arraySep:';'代码>,自,对吗?(我知道'header:true'和sep:','
也是默认值)。你说得对。我相应地简化了我的答案。最后一个更新:我现在想为每个邻居创建单独的节点,并为每个指向相关人员的邻居创建一个邻居关系。如何将其添加到查询中?最后一个问题:我现在想为每个邻居创建单独的节点,并为每个指向相关人员的邻居创建一个邻居关系。如何将其添加到查询中@CyberSAM创建一个人的邻居节点(如果不存在)和从每个邻居返回到该人的关系(如果不存在):匹配(p:person)FOREACH(n IN p.neights | MERGE(m:person{name:n})MERGE(m)-[:neighter\u OF]->(p)
。新创建的邻居节点将没有索引
属性。
╒══════════════════════════════════════════════════════════════════════╕
│"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":[]} │
└──────────────────────────────────────────────────────────────────────┘
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}
);