Reputation: 589
I want to find all loops that originate and terminate with a specific node in a Neo4j database. I tried:
START n=node:Event(time=",timestamp,")
MATCH p=(n)-[:LINKED_TO*1..5]->(n)
WHERE NONE (n IN nodes(p) WHERE size(filter(x IN nodes(p) WHERE n = x))> 2)
RETURN p, length(p)
This is the best I can mashup from what is on the web. There are two things I don't like about this: 1. it crashes 2. the count threshold must be ">2" to allow for the start+termination node. That means that loops that visit the same intermediate node twice will be included, which I wish was not the case.
I'm not interested in the shortest path. I want to know all loops that return to my starting node.
Thank you in advance!
Upvotes: 0
Views: 662
Reputation: 589
This what finally worked for me. It is very close to what cybersam suggested. Apologies for doing this "the wrong way". I'm sure cybersam will yell at me, again, but adding code via Comment is not very easy to read.
MATCH p=(n:Event{time:",timestamp,"})-[:LINKED_TO*1..5]->(n)
UNWIND TAIL (NODES(p)) AS m
WITH p,COUNT(DISTINCT m) AS cm
WHERE LENGTH(p) = cm
RETURN p
As I noted earlier, one sticking point was the use of "START", which is deprecated and causes errors (for example, when using RNeo4j in R, which I'm using). The new way appears to be to use MATCH and specify your starting node in the path pattern. The other confusing thing for me was the use of "LENGTH(p)-1" instead of "LENGTH(p)". For one node connecting to another, the path has a length of 2, not 3 and there are only 2 distinct nodes. For my application, "LENGTH(p)=cm" worked.
Finally, if you want the nodes in the paths, do NOT try to use "WITH m,..." because this messes up the "COUNT(DISTINCT(m))" computation for some reason that I do not understand.
Upvotes: 0
Reputation: 589
Thank you, cybersam! That was helpful. As typed, it gave a few errors and warned me that "START" is deprecated. I found the following modifications worked:
MATCH (n:Event{time:1458238060505007})
MATCH p=(n)-[:LINKED_TO*1..5]->(n)
UNWIND TAIL(NODES(p)) AS m WITH p RETURN p
The only problem with this is that it appears to give all paths that go through the desired start node, n. Is that true? If so, is there a way to correct this?
Upvotes: 0
Reputation: 67019
This query should return all loops that start and end at the specified node and have no other repeated nodes:
START n=node:Event(time=",timestamp,")
MATCH p=(n)-[:LINKED_TO*1..5]->(n)
UNWIND TAIL(NODES(p)) AS m
WITH p, COUNT(DISTINCT m) AS cm
WHERE LENGTH(p)-1 = cm
RETURN p, LENGTH(p);
Upvotes: 1