1
votes

I have a bunch of nodes that "refer" to other nodes. The nodes referred to (refer_to being the relationship) may then have a relationship to another node called changed_to. Those nodes that are related by the changed_to relationship may also have another changed_to relationship with yet another node. I want to return the nodes referred to, but also the nodes that the referred nodes were changed into. I tried a query that returns referred to nodes combined with a union with an optional match of ReferencedNode changed to ResultNode, but I don't think this will work as it will only get me the referenced node plus the first changed to node and nothing after that, assuming that would work at all to begin with. How can I make a query with the described behavior?

Edit: This is an example of the relationships going on. I would like to return the referenced to node and the node that the referenced node was ultimately became, with some indicator showing that it became that node ultimately.

enter image description here

2
A diagram of your network and the queries you tried so far would help.Martin Preusse
Here is clip out of the database. If there is no changed to relationship, I only want the referred to node, but if there is, I want the node that was originally referred to, plus the last node it became.cluemein

2 Answers

1
votes

Can you give some examples of queries you've tried? Here's what I'm thinking:

MATCH path=(n)-[:refer_to]->(o)-[:changed_to*1..5]->(p)
WHERE n.id = {start_id}
RETURN nodes(path), rels(path)

Of course I don't know if you have an id property so that might need to change. Also you'll be passing in a start_id parameter here.

0
votes

If you want to return the "references" node and the last "changed_to" node if there is one, you can first match the relationship you know is there, then optionally match at variable depth the path that may be there. If there is more than one "changed_to" relationship you will have more than one result item at this point. If you want all the "changed_to" nodes you can return now, but if you want only the last one you can order the result items by path depth descending with a limit of 1 to get the longest path and then return the last node in that path. That query could look something like

MATCH (n)-[:REFERENCES]->(o)
WHERE n.uid = {uid}
OPTIONAL MATCH path=o-[:CHANGED_TO*1..5]->(p)
WITH n, o, path
ORDER BY length(path) DESC
LIMIT 1
RETURN n, o, nodes(path)[-1]

This returns the start node, the "references" node and

  • nothing when there is no "changed_to" node
  • the one "changed_to" node when there is only one
  • the last "changed_to" node when there is more than one

You can test the query in this console. It contains these three cases and you can test them by replacing {uid} above with the values 1,5 and 8 to get the starting nodes for the three paths.