简体   繁体   中英

How can I create relationships in neo4j/Cypher from a csv that depend on the type of nodes?

I am trying to import a csv into Neo4j that contains relationships between people, organizations, banks, assets, etc., where there is only one relationship per row. The column names are FROM, A.Type, TO, B.type , and then different properties. Here, the from and to labels have the name, and AB.type say if it belongs to a person, org., etc. respectibly.

I managed to create the nodes (around 3500) depending on type with FOREACH , like so:

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}))

. . .

My problem now is creating the relationships per row, I've tried many different ways and nothing seems to work. For Example:

  1. In this case, I changed the FOREACH to two different nodes depending on if they are on the FROM or TO column:
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) 
  1. I also tried a variation of the code for creating nodes:

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)))

  1. This time I used the APOC library to try generating dinamic relationships depending on the relashionship type:
WITH asset, organization, line
CALL apoc.create.relationship(asset, line.RelationshipType, NULL, organization) YIELD rel
RETURN asset, rel, organization

And different variations of each, creating the nodes from scratch or matching them. Everytime the query seems to work, it runs, but it creates no relationships or it creates a single relationship between new nodes that don't exist in the csv, with no name or label.

I am completely new to Cypher/Neo4j and am at my wits end, if someone could point out my mistakes and how to correct them, it would be HIGHLY appreciated.

Thank you in advance!

  • You should be using A.type and B.type when appropriate.
  • Since the nodes already exist, you should replace the 2 existing MERGE clauses with MATCH clauses.
  • If you want to ensure you don't create duplicate relationships, you should use MERGE instead of CREATE for the relationship.
  • You can use the APOC procedure apoc.do.case to perform conditional write operations.

For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM