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
Related
I want to find the depth of the tree
I have found this solution but I do not know whether it's true for all the cases:
MATCH p=(parent)-[:RELATES*]->(child)
WHERE id(parent) = 30
RETURN p
ORDER BY length(p) DESC
limit 1
This gives me the longest path, but
firstly: I don't know if it's always valid.
Secondly: I want the output to be a number of the depth not the List itself.
This query should work:
MATCH p=(parent)-[:RELATES*]->(child)
WHERE ID(parent) = 30 AND NOT (child)-[:RELATES]>()
RETURN LENGTH(p) AS maxLth
ORDER BY maxLth DESC
LIMIT 1
Although not strictly necessary, it only considers paths where child is a leaf.
as #cybersam mentioned with little bit of tweaking:
MATCH p=(parent)-[:RELATES*]->(child)
WHERE ID(parent) = 30 AND NOT (child)-[:RELATES]>()
RETURN LENGTH(p) + 1 AS maxLth
ORDER BY maxLth DESC
LIMIT 1
I want to compute Indegree and Outdegree and return a graph that has a connection between top 5 Indegree nodes and top 5 Outdegree nodes. I have written a code as
match (a:Port1)<-[r]-()
return a.id as NodeIn, count(r) as Indegree
order by Indegree DESC LIMIT 5
union
match (n:Port1)-[r]->()
return n.id as NodeOut, count(r) as Outdegree
order by Outdegree DESC LIMIT 5
union
match p=(u:Port1)-[:LinkTo*1..]->(t:Port1)
where u.id in NodeIn and t.id in NodeOut
return p
I get an error as
All sub queries in an UNION must have the same column names (line 4, column 1 (offset: 99)) "union"
What are the changes that I need to do to the code?
There's a few things we can improve.
The matches you're doing isn't the most efficient way to get incoming and outgoing degrees for relationships.
Also, UNION can only be used to combine query results with identical columns. In this case, we won't even need UNION, we can use WITH to pipe results from one part of a query to another, and COLLECT() the nodes you need in between.
Try this query:
match (a:Port1)
with a, size((a)<--()) as Indegree
order by Indegree DESC LIMIT 5
with collect(a) as NodesIn
match (a:Port1)
with NodesIn, a, size((a)-->()) as Outdegree
order by Outdegree DESC LIMIT 5
with NodesIn, collect(a) as NodesOut
unwind NodesIn as NodeIn
unwind NodesOut as NodeOut
// we now have a cartesian product between both lists
match p=(NodeIn)-[:LinkTo*1..]->(NodeOut)
return p
Be aware that this performs two NodeLabelScans of :Port1 nodes, and does a cross product of the top 5 of each, so there are 25 variable length path matches, which can be expenses, as this generates all possible paths from each NodeIn to each NodeOut.
If you only one the shortest connection between each, then you might try replacing your variable length match with a shortestPath() call, which only returns the shortest path found between each two nodes:
...
match p = shortestPath((NodeIn)-[:LinkTo*1..]->(NodeOut))
return p
Also, make sure your desired direction is correct, as you're matching nodes with the highest in degree and getting an outgoing path to nodes with the highest out degree, that seems like it might be backwards to me, but you know your requirements best.
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;
I am using Cyper query in neo4j
My requirement is,
need to get two level unique(friends) and their shortest depth value.
Graph looks like,
a-[:frnd]->b, b-[:frnd]->a
b-[:frnd]->c, c-[:frnd]->b
c-[:frnd]->d, d-[:frnd]->c
a-[:frnd]->c, c-[:frnd]->a
I tried as,
START n=node(8) match p=n-[:frnd*1..2]->(x) return x.email, length(p)
My output is,
b 1 <--length(p)
a 2
c 2
c 1
d 2
a 2 and so on.
My required output,
My parent node(a) should not not be listed.
I need only (c) with shortest length 1
c with 2 should not be repeated.
Pls help me to solve this,.
(EDITED. Finding n via START n=node(8) causes problems with other variables later on. So, below we find n in the MATCH statement.)
MATCH p = shortestPath((n {email:"a"})-[:frnd*..2]->(x))
WHERE n <> x AND length(p) > 0
RETURN x.email, length(p)
ORDER BY length(p)
LIMIT 1
If there are multiple "closest friends", this returns one of them.
Also, the shortestPath() function does not support a minimal path length -- so "1..2" had be become "..2", and the WHERE clause needed to specify length(p) > 0.
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