如何根据节点类型从 csv 在 neo4j/Cypher 中创建关系?
How can I create relationships in neo4j/Cypher from a csv that depend on the type of nodes?
我正在尝试将一个 csv 导入 Neo4j,其中包含人员、组织、银行、资产等之间的关系,其中每行只有一个关系。列名分别是FROM、A.Type、TO、B.type,然后是不同的属性。这里的 from 和 to 标签都有名字,A-B.type 表示它是否属于一个人,组织等。
我根据 FOREACH
的类型设法创建了节点(大约 3500 个),如下所示:
FOREACH (_ IN CASE WHEN line.`A.type` = 'ASSET' THEN [1] ELSE [] END | MERGE (asset:Asset {Name:line.FROM}))
FOREACH (_ IN CASE WHEN line.`A.type` = 'BANK' THEN [1] ELSE [] END | MERGE (bank:Bank {Name: line.FROM}))
。
.
.
FOREACH (_ IN CASE WHEN line.`B.type` = 'ACTIVO' THEN [1] ELSE [] END | MERGE (asset:Asset {Name:line.TO}))
FOREACH (_ IN CASE WHEN line.`B.type` = 'BANCO' THEN [1] ELSE [] END | MERGE (bank:Bank {Name: line.TO}))
。
.
.
我现在的问题是创建每行的关系,我尝试了很多不同的方法,但似乎没有任何效果。
例如:
- 在这种情况下,我将
FOREACH
更改为两个不同的节点,具体取决于它们是在 FROM 还是 TO 列:
WITH 'link' as line
LOAD CSV WITH HEADERS FROM url AS line
WITH line WHERE line.FROM = 'ASSET' AND line.TO = 'ORGANIZATION'
MERGE (a1:Asset {Name:line.FROM})
MERGE (o2:Organization {Name:line.TO})
CREATE (a1)-[con:PROPERTY_OF]->(o2)
- 我还尝试了用于创建节点的代码变体:
FOREACH(n IN (CASE WHEN line.`A.type` = 'ASSET' THEN [1] ELSE [] END) | FOREACH(t IN CASE WHEN line.`B.type` = 'ORGANIZATION' THEN [1] ELSE [] END | MERGE (asset)-[ao:CONNECTED_WITH]->(organization)))
- 这次我使用 APOC 库尝试根据关系类型生成动态关系:
WITH asset, organization, line
CALL apoc.create.relationship(asset, line.RelationshipType, NULL, organization) YIELD rel
RETURN asset, rel, organization
以及每个的不同变体,从头开始创建节点或匹配它们。每次查询似乎有效时,它都会运行,但它不会创建任何关系,或者它会在 csv 中不存在的新节点之间创建单一关系,没有名称或标签。
我是 Cypher/Neo4j 的新手,不知所措,如果有人能指出我的错误以及如何改正它们,我们将不胜感激。
提前致谢!
- 您应该在适当的时候使用
A.type
和 B.type
。
- 由于节点已经存在,您应该将 2 个现有的
MERGE
子句替换为 MATCH
子句。
- 如果您想确保不创建重复的关系,您应该对关系使用
MERGE
而不是 CREATE
。
- 您可以使用 APOC 程序 apoc.do.case 执行条件写入操作。
例如:
LOAD CSV WITH HEADERS FROM 'file:///' AS line
CALL apoc.do.case([
line.`A.type` = 'ASSET' AND line.`B.type` = 'ORGANIZATION',
'MATCH (a:Asset {Name: line.FROM}), (b:Organization {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b',
line.`A.type` = 'ASSET' AND line.`B.type` = 'BANCO',
'MATCH (a:Asset {Name: line.FROM}), (b:Bank {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b',
line.`A.type` = 'BANK' AND line.`B.type` = 'ACTIVO',
'MATCH (a:Bank {Name: line.FROM}), (b:Asset {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b'
],
'', // empty ELSE case
{line: line}
) YIELD value
RETURN value
我正在尝试将一个 csv 导入 Neo4j,其中包含人员、组织、银行、资产等之间的关系,其中每行只有一个关系。列名分别是FROM、A.Type、TO、B.type,然后是不同的属性。这里的 from 和 to 标签都有名字,A-B.type 表示它是否属于一个人,组织等。
我根据 FOREACH
的类型设法创建了节点(大约 3500 个),如下所示:
FOREACH (_ IN CASE WHEN line.`A.type` = 'ASSET' THEN [1] ELSE [] END | MERGE (asset:Asset {Name:line.FROM}))
FOREACH (_ IN CASE WHEN line.`A.type` = 'BANK' THEN [1] ELSE [] END | MERGE (bank:Bank {Name: line.FROM}))
。 . .
FOREACH (_ IN CASE WHEN line.`B.type` = 'ACTIVO' THEN [1] ELSE [] END | MERGE (asset:Asset {Name:line.TO}))
FOREACH (_ IN CASE WHEN line.`B.type` = 'BANCO' THEN [1] ELSE [] END | MERGE (bank:Bank {Name: line.TO}))
。 . .
我现在的问题是创建每行的关系,我尝试了很多不同的方法,但似乎没有任何效果。 例如:
- 在这种情况下,我将
FOREACH
更改为两个不同的节点,具体取决于它们是在 FROM 还是 TO 列:
WITH 'link' as line
LOAD CSV WITH HEADERS FROM url AS line
WITH line WHERE line.FROM = 'ASSET' AND line.TO = 'ORGANIZATION'
MERGE (a1:Asset {Name:line.FROM})
MERGE (o2:Organization {Name:line.TO})
CREATE (a1)-[con:PROPERTY_OF]->(o2)
- 我还尝试了用于创建节点的代码变体:
FOREACH(n IN (CASE WHEN line.`A.type` = 'ASSET' THEN [1] ELSE [] END) | FOREACH(t IN CASE WHEN line.`B.type` = 'ORGANIZATION' THEN [1] ELSE [] END | MERGE (asset)-[ao:CONNECTED_WITH]->(organization)))
- 这次我使用 APOC 库尝试根据关系类型生成动态关系:
WITH asset, organization, line
CALL apoc.create.relationship(asset, line.RelationshipType, NULL, organization) YIELD rel
RETURN asset, rel, organization
以及每个的不同变体,从头开始创建节点或匹配它们。每次查询似乎有效时,它都会运行,但它不会创建任何关系,或者它会在 csv 中不存在的新节点之间创建单一关系,没有名称或标签。
我是 Cypher/Neo4j 的新手,不知所措,如果有人能指出我的错误以及如何改正它们,我们将不胜感激。
提前致谢!
- 您应该在适当的时候使用
A.type
和B.type
。 - 由于节点已经存在,您应该将 2 个现有的
MERGE
子句替换为MATCH
子句。 - 如果您想确保不创建重复的关系,您应该对关系使用
MERGE
而不是CREATE
。 - 您可以使用 APOC 程序 apoc.do.case 执行条件写入操作。
例如:
LOAD CSV WITH HEADERS FROM 'file:///' AS line
CALL apoc.do.case([
line.`A.type` = 'ASSET' AND line.`B.type` = 'ORGANIZATION',
'MATCH (a:Asset {Name: line.FROM}), (b:Organization {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b',
line.`A.type` = 'ASSET' AND line.`B.type` = 'BANCO',
'MATCH (a:Asset {Name: line.FROM}), (b:Bank {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b',
line.`A.type` = 'BANK' AND line.`B.type` = 'ACTIVO',
'MATCH (a:Bank {Name: line.FROM}), (b:Asset {Name: line.TO}) MERGE (a)-[:FOO]->(b) RETURN a, b'
],
'', // empty ELSE case
{line: line}
) YIELD value
RETURN value