Importing data string where the string is a path


(Thebestnom) #1

I am importing from a very old db I have.
It saves relationship only for display so it is saved as stirng like "a/b/c/d" where the path is a->b->c->d of the same label.
Each row have this path and im trying to make a new node where it connected to the graph on d, the problem is that the string does not have a constant length of relations and I cant find how to do it in cypher?

I already have the graph and I only need to get the last node in the path (d in this case), can it be done in only cypher?
Any procedure is fine


(Andrew Bowman) #2

What are each of these? Are a, b, c, and d different labels? We need to know what these things are in order to provide any advice.


(Thebestnom) #3

Same label, different nodes... Sorry for being not clear...
I edited the original post


(Andrew Bowman) #4

I'm still rather confused here. Can you provide an example string, and show us how the elements of the string representation match up with the actual nodes in your graph? Are there properties in the string that are meant to match up to unique node properties? We'll need to know how the string representation maps onto your graph representation first.

Also, since this is an import, it would be a good idea to replace these string paths with actual relationships between nodes, that will make your use case easier in the end I think.


(Thebestnom) #5

Ok, sorry for the confusion, so lets say I have a hierarchy of countries North America->USA->Washington->Street 5, and I have a list of manager in a sql server, and in each row I have the manager name and what does he manage, so a an example row is name: John, manage:"North America/USA/Washington"
I Want a new node John under Washington node.
While in this example I could just take the last and search for it, in an example of someone who manage Street 5 ill need to travel on the graph to know which street 5.
Im hoping I am clear now :sweat_smile:


(Andrew Bowman) #6

Provided that your nodes in question already have relationships between them, and provided that you have indexes on those nodes by name (and probably something like a :Location label), you will want to do a MATCH on a pattern to verify that you're looking at the right node (there are various Springfield cities in different states, for example).

Probably the easiest way is to split the hierarchy into a list, start your match to the last node in the hierarchy and MATCH to it and everything above it (should be a 4 or 5 hop traversal), extract the properties in question (hopefully they're all using a common property, like 'name'), then compare to your hierarchy list. That should narrow you down to the correct node, and you can MERGE a new node onto it.

Something like this:

// assume $input is the string path, and $managerName is the name of the manager to add
WITH split($input, '/') as pathList
WITH pathList, last(pathList) as startName
MATCH path = (root)-[:CONTAINS*0..]->(start:Location {name:startName})
WHERE NOT ()-[:CONTAINS]->(root) AND [node in nodes(path) | node.name] = pathList
MERGE (p:Person {name:$managerName}) // :Person(name) ought to be unique in this case
MERGE (start)<-[:MANAGES]-(p)

(Thebestnom) #7

Wow, thanks it works great!

It was wierd for me at the start that you go bottom up (which makes perfectly sense after thinking about it), and also as js developer that list equality is deepEqual :sweat_smile:.

Just last question, what I was originally expected was a way to recursively match from up to bottom each node at a time (find North America, than North America to USA than USA to Washington and so on), is there any way to do it?