2

Neo4j 2.1.7

Attempting to mass-connect a bunch of nodes via information I've received in a CSV, which looks like:

person_id,book_id,relationship
111,AAA,OWNS
222,BBB,BORROWS
333,AAA,BORROWS

The nodes :Person and :Book used in this CSV were successfully loaded via LOAD CSV and CREATE statements, and already exist in the database. Now, I'd like to load this above CSV of relationships between :Person and :Book. The relationships are defined in the CSV itself.

LOAD CSV WITH HEADERS FROM "file:data.csv" AS row
MATCH (person:Person { personID: row.person_id })
MATCH (book:Book { bookID: row.book_id })

Sure, the next MERGE command works if I supply a specific name ([:OWNS], [:BORROWS], etc.) but as you can see, my relationships are supplied by the incoming data.

However, I'd like the relationship defined in MERGE to not be a "hard-coded" string, but come as data from the 3rd column of my CSV instead. Something along the lines of:

MERGE (person)-[row.relationship]->(book)

Is this even possible?

PS: I've tried the syntax above, and also -[:row.relationship]->, both to no avail (syntax errors)

changingrainbows
  • 2,551
  • 1
  • 28
  • 35
  • you can use CLI tools [batch-import](https://github.com/jexp/batch-import), or, if you upgrade to 2.2.0 (which is not yet stable), [neo4j-import](http://neo4j.com/docs/milestone/import-tool.html) – zaboco Feb 19 '15 at 10:16

1 Answers1

2

I don't think it is possible with LOAD CSV. You need to do a little trickery with the input data and collections. If the relationship in the input csv contains OWNS create a collection with a one in it otherwise create an empty collection. Do the same for the BORROWS relationship value. It will be something like this...

...
case when row.relationship = "OWNS" then [1] else [] end as owns
case when row.relationship = "BORROWS" then [1] else [] end as borrows
foreach(x in owns | MERGE (person)-[:OWNS]->(book))
foreach(x in borrows | MERGE (person)-[:BORROWS]->(book))
...
Dave Bennett
  • 10,996
  • 3
  • 30
  • 41
  • Funny how seemingly obvious solutions come up only when mentioned by someone else. For the (small) data size, I'm dealing with, with low diversity of relationship types, this solution is totally acceptable. I can see this not scaling too well with a lot of relationships and a massive CASE statement, but it'll definitely do the trick. – changingrainbows Feb 19 '15 at 15:50
  • 1
    Agree. I grappled with the same. I think with many it would be combersom and you would probably resort to post processing with a program of some kind. Create somthing like `-[:BOOKREL {type: row.relationship}]->` in the load and then afterwards write a little program to create the relationships the way you want. I learned the trick above from Wes Freeman at GraphConnect last fall. – Dave Bennett Feb 19 '15 at 15:59
  • 1
    In my neo4j-shell tools you can use placeholders like #{relationship} for the labels and rel-types, just in case for larger imports: https://github.com/jexp/neo4j-shell-tools#cypher-import – Michael Hunger Feb 21 '15 at 11:41