I struggle to return the node with the largest value, and process that node further.
Here's how I would return a node with the largest value:
START n=node(startnode)
MATCH n-[:TYPE]-m
RETURN m
ORDER BY m.value DESC LIMIT 1
but now I am in a subquery
START n=node(somenode)
MATCH n-[:TYPE1]-q
WITH DISTINCT q
MATCH q-[:TYPE2]-m
and then the ORDER BY .. LIMIT 1 obviously doesn't work anymore because I want one result for each q.
How is this done?
Also, once I have the m with largest value for each q I'll also need to process it:
RETURN q, m.maxvalue, x.anothervalue
from
MATCH m-[:HAS_ONE_LINK_TO]->x
So while I've been playing with collections (collect(m) ), I haven't figured a way to expand them back to "result rows" for applying that MATCH.
Untested... let me know if it works for you:
START n=node(somenode)
MATCH n-[:TYPE1]-q // initial query
WITH DISTINCT q
MATCH q-[:TYPE2]-m
WITH q, max(m.value) as max // get max for q
MATCH q-[:TYPE2]-m
WHERE m.value = max // find the max m for each q
WITH q, m
MATCH m-[:HAS_ONE_LINK_TO]->x // find x from m
RETURN q, m, x
Edit: because of recent upvotes on this old answer... please consider a fresher query written in 3.x era using collect/unwind -- also untested (take care to not do this if the number of ms will be quite large, as they may be stored in the partial result of the query instead of being able to stream them):
MATCH (n:Label)-[:TYPE1]-(q) // initial query
WITH DISTINCT q
MATCH (q)-[:TYPE2]-(m)
WITH q, max(m.value) as max, collect(m) as ms // get max for q, collect ms
UNWIND ms as m
WHERE m.value = max
MATCH (m)-[:HAS_ONE_LINK_TO]->(x) // find x from m
RETURN q, m, x
Related
I found the following information on how to calculate the size of neo4j database: https://neo4j.com/developer/guide-sizing-and-hardware-calculator/#_disk_storage
An example disk space calculation is:
10,000 Nodes x 14B = 140kB 1,000,000 Rels x 33B = 31.5MB 2,010,000
Props x 41B = 78.6MB
Total is 110.2MB
Is there a query that could simply fetch this information for me?
For the node count the query is simple:
match (n) return count(n);
for the rel count the query would be as follows:
match (n)-[r]-() return count(r);
How do I get the count of all properties of all nodes and relations combined though?
Answering your main question, use the keys function to get a list of property names and summarize their length:
MATCH (n)
WITH SUM(SIZE(KEYS(n))) AS countOfNodeProps,
COUNT(n) AS countOfNodes
MATCH ()-[r]->()
WITH countOfNodeProps,
countOfNodes,
SUM(SIZE(KEYS(r))) AS countOfRelProps,
COUNT(r) AS countOfRels
RETURN countOfNodeProps,
countOfRelProps,
(countOfNodeProps + countOfRelProps) as countOfProps,
countOfNodes,
countOfRels
But it's easier to use the apoc.monitor.store function to get the exact information about the storage:
CALL apoc.monitor.store() YIELD
logSize,
stringStoreSize,
arrayStoreSize,
relStoreSize,
propStoreSize,
totalStoreSize,
nodeStoreSize
RETURN *
in my neo4j graph DB I have issues and persons as my nodes, and relationships are "links" (issue to issue), and "resource" (issue to person).
I'm interested in finding all paths of issues where the sum of their weights is greater than a threshold y and the overall length of the chain is longer than x.
I'm not sure if the following works, as I think it just gives me issues with 5 links
MATCH (s:Issue)-[rs:links*5..]->(m:Issue)
WITH s, rs, m
unwind rs as r
return s AS source_node,
id(s) AS source_id,
r,
m AS target_node,
id(m) AS target_id
I've tried with count as well but I don't think it is the right way to proceed.
To do this, use REDUCE() to accumulate the weights of relationships. Consider a x = 5 and y = 200:
MATCH (s:Issue)-[rs:links*5..]->(m:Issue) // match depths with 5 (x) or more
WITH REDUCE(weights = 0, rel IN rs | weights + rel.weight) AS total_weight, s, rs, m
WHERE total_weight < 100 // filter by total_weight < y (100)
unwind rs as r
return s AS source_node,
id(s) AS source_id,
r,
m AS target_node,
id(m) AS target_id
Imagine that i have a graph in which for every pair of nodes m,n of type Nod1 there can be a node k of type Nod2 that connect them through relationships of type Rel, that is, there can be multiple patterns of the kind p=(m:Nod1)-[r:Rel]-(k:Nod2)-[s:Rel]-(n:Nod1). For a given node m (satisfying for example m.key="whatever") how can i find the node n that maximizes the number of nodes k that connect m to n? For example: imagine that there are 3 nodes k that connects m to n1 satisfying n1.key="hello" and 10 nodes k that connects m to n2 satisfying n2.key="world"; how to build a query that retrieves the node n2? :)
The title of the question is count duplicated, because i think that the problem is solved if i can count all "duplicated" patterns for each node n (that is, all patterns that has n as "endnode")!! :)
Start by matching your m; then match the pattern you want, then filter by distinct n nodes, and count the number of k nodes connected via that n node, and you should be there.
MATCH (m:Nod1 { key: "whatever" })
WITH m
MATCH (m)-[r:Rel]-(k:Nod2)-[s:Rel]-(n:Nod1)
RETURN distinct(n), count(k) as x
ORDER BY x DESC;
I have this query in Neo4j:
MATCH (sentence:Sentence)-[r*]->(n:Word )
WITH n, COUNT(r) AS c
RETURN n, c
My graph is a linguistic database containing words and dependency relations between them.
This query should return depth of nodes, however the COUNT(r) always returns 1.
When I ommit the COUNT function and write just
WITH n, r AS c
instead (trying in web browser neo4j interface), neo4j returns multiple relations for each word node "n" as expected.
Can you please help me what am I doing wrong, how to count the length of path between sentence node and word node? thanks.
I think it query return n and c and there are multiple record of n so count(r) return 1.
Try this -
MATCH (sentence:Sentence)-[r*]->(n:Word )
WITH n, LENGTH(r) AS depth
RETURN n, depth
You will get depth like this.
Or Try this
MATCH p= (sentence:Sentence)-->(n:Word)
RETURN n, length(p) as depth
http://docs.neo4j.org/chunked/stable/query-functions-scalar.html#functions-length
Finally found the solution myself - it is cypher's LENGTH function:
MATCH (sentence:Sentence)-[r*]->(n:Word )
WITH n, LENGTH(r) AS c
RETURN n, c
found in this useful cheat sheet: http://assets.neo4j.org/download/Neo4j_CheatSheet_v3.pdf
In version 4.x, U should use SIZE function
MATCH (sentence:Sentence)-[r*]->(n:Word )
WITH n, SIZE(r) AS depth
RETURN n, depth
https://neo4j.com/docs/cypher-manual/current/functions/scalar/#functions-size
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.