Determine the Longest Unidirectional Path in a Directed Disconnected Graph - neo4j

I have a directed disconnected graph in which some vertices (nodes) can be connected by multiple unidirectional relationships of different types. It is possible that the graph has loops.
How can I determine the length of the longest unidirectional path in my graph? I have been trying the following query with no success:
START n=node(*)
MATCH p=n<-[rels]-m
WITH COLLECT(p) AS paths, MAX(length(p)) AS maxLength
RETURN FILTER(path IN paths
WHERE length(path)= maxLength) AS longestPaths
Thanks in advance,

What about:
MATCH p=(n)<-[:RELTYPE*]-(m)
RETURN length(p)
ORDER BY LENGTH(p) DESC
LIMIT 1
Be aware that this kind of query might be expensive depending the structure and size of your graph.
For Neo4j 1.9 use:
START n=node(*)
MATCH p=(n)<-[:RELTYPE*]-(m)
RETURN length(p)
ORDER BY LENGTH(p) DESC
LIMIT 1

Related

Find max depth with bidiretional graph

using neo4j I'm trying to find max depth in this graph:
Using this query I find deph value 20 (because I have this bidirectional relationship):
MATCH p=(u:User)-[:Amico*]->(f:User)
RETURN p, length(p) order by length(p) desc limit 1
How can I have the true value of this depth?
I guess you could solve it by only considering paths in which each node only appears once. Neo4j's apoc library offers a function for that:
MATCH p=(u:User)-[:Amico*]->(f:User)
WHERE NOT apoc.coll.containsDuplicates(nodes(p))
RETURN p, length(p) order by length(p) desc limit 1

Neo4j: get all relations between queried nodes

I want to make a cypher query that do below tasks:
there is a given start node, and I want to get all related nodes in 2 hops
sort queried nodes by hops asc, and limit it with given number
and get all relations between result of 1.
I tried tons of queries, and I made below query for step 1, 2
MATCH path=((start {eid:12018})-[r:REAL_CALL*1..2]-(end))
WITH start, end, path
ORDER BY length(path) ASC
RETURN start, collect(distinct end)[..10]
But when I try to get relationships in queried path with below query, it returns all relationships in the path :
MATCH path=((start {eid:12018})-[r:REAL_CALL*1..2]-(end))
WITH start, end, path
ORDER BY length(path) ASC
RETURN start, collect(distinct end)[..10], relationships(path)
I think I have to match again with result of first match instead of get relationships from path directly, but all of my attempts have failed.
How can I get all relationships between queried nodes?
Any helps appreciate, thanks a lot.
[EDITED]
Something like this may work for you:
MATCH (start {eid:12018})-[rels:REAL_CALL*..2]-(end)
RETURN start, end, COLLECT(rels) AS rels_collection
ORDER BY
REDUCE(s = 2, rs in rels_collection | CASE WHEN SIZE(rs) < s THEN SIZE(rs) ELSE s END)
LIMIT 10;
The COLLECT aggregation function will generate a collection (of relationship collections) for each distinct start/end pair. The LIMIT clause limits the returned results to the first 10 start/end pairs, based on the ORDER BY clause. The ORDER BY clause uses REDCUE to calculate the minimum size of each path to a given end node.

Cypher query to find the longest path using neo4j 3.1.0 version

Can anybody send the Cypher query to find LONGEST PATH between two nodes using neo4j 3.1.0 version.
The graph algorithm to find the longest path is not implemented.
Here is a Cypher query that gets all paths and sorts them by size:
// get the nodes
MATCH (a:Node), (b:Node)
WHERE ID(a) = 14 AND ID(b) = 7
WITH a,b
// match all paths
MATCH p=(a)-[*]-(b)
// return the longest
RETURN p, length(p) ORDER BY length(p) DESC LIMIT 1
However, without any restrictions on the query, this might not work on large graphs. Finding the longest path in an undirected graph is expensive: https://en.wikipedia.org/wiki/Longest_path_problem
And without restrictions on the query (direction and relationship type) the query will look for all undirected paths.
You should restrict your path query or try two solve your problem without the longest path.
If you are looking for the longest path between nodes where each node in the chain has the same relationship to the next then see Achieving longestPath Using Cypher which shows:
MATCH p=(parent:Entity)-[:HAS_CHILD*1..10]->(child:Person)
WHERE size((child)-[:HAS_CHILD]->()) = 0
RETURN child;
However I am using:
MATCH (parent:Entity)-[:HAS_CHILD*1..10]->(child:Person)
WHERE NOT (child)-[r:HAS_CHILD]->()
RETURN child;
If anyone can comment on performance or any other aspect please do!
I also discovered an undocumented feature which will return the child when it is also the parent (as in only one node):
MATCH (parent:Entity)-[:HAS_CHILD*0..]->(child:Person)
WHERE NOT (child)-[r:HAS_CHILD]->()
RETURN child;

neo4j how to use count(distinct()) over the nodes of path

I search the longest path of my graph and I want to count the number of distinct nodes of this longest path.
I want to use count(distinct())
I tried two queries.
First is
match p=(primero)-[:ResponseTo*]-(segundo)
with max(length(p)) as lengthPath
match p1=(primero)-[:ResponseTo*]-(segundo)
where length(p1) = lengthPath
return nodes(p1)
The query result is a graph with the path nodes.
But if I tried the query
match p=(primero)-[:ResponseTo*]-(segundo)
with max(length(p)) as lengthPath
match p1=(primero)-[:ResponseTo*]-(segundo)
where length(p1) = lengthPath
return count(distinct(primero))
The result is
count(distinct(primero))
2
How can I use count(distinct()) over the node primero.
Node Primero has a field called id.
You should bind at least one of those nodes, add a direction and also consider a path-limit otherwise this is an extremely expensive query.
match p=(primero)-[:ResponseTo*..30]-(segundo)
with p order by length(p) desc limit 1
unwind nodes(p) as n
return distinct n;

neo4j get nodes in order of connections

http://console.neo4j.org/r/z1iafh is it possible to return n.name in order so it would be CREATE (node_name); without adding new properties to nodes? I see that there is a sequence in which nodes in this test database are connected to each other, so i am interested is it possible to somehow het this sequence.
START n=node(*) MATCH (n)-[r:CREATE_NODE_COMMAND]->(m) RETURN n
First you need to declare a path identifier, then add depth and lastly you can order by path length :
START n=node(*) MATCH p=(n)-[r:CREATE_NODE_COMMAND*..10]->(m)
ORDER BY length(p)
LIMIT 1
RETURN nodes(p)

Resources