Neo4j 1.9.RC2, cypher sorting and ranking - neo4j

i am using Neo4j 1.9.RC2 and i test the ORDER BY with WITH.
What i want to do is to generate a dynamic ranking and store the current sort index into each node sorted.
i have something like : parent-[r:has_child]->rank_node
I would like to do something like :
start n=node(1)
match n-[r:has_child]->rank_node
with rank_node
order by rank_node.score
set rank_node.position = "CURRENT ORDER BY INDEX"
I woul like to have a counter that increment from 0 to "n" ... I can't manage to do that ...
Here CURRENT ORDER BY INDEX is like the current index of each node return by order by.
i don't know if it is possible to do that with cyper? It would be very usefull because we can do big sorting and insert directly the position in the node to get it later directly ...

Talked to Michael Hunger and we solved it like this:
start n=node(0)
match n-[r:rank]->rank_node
with rank_node, n
match n-[r:rank]->rn
where rn.score <= rank_node.score
with rank_node,count(*) as pos
set rank_node.rank = pos
return rank_node;
For live example see: http://console.neo4j.org/?id=d07p7r

MATCH (a:person)
OPTIONAL MATCH ()-[r:knows|knowsyy]->(a)
RETURN COUNT(*) AS rank,a.mobno // //rank with two direction
person=label
know and knowsyy=relation

MATCH (n:person)-[r:knows]->(a:phonbook)
RETURN COUNT(*) AS rank,n.mobno,r.name ORDER BY n.mobno desc //rank with relation

Related

Neo4j Update node with aggregated count

I'm trying to take a count and set a property of a node with the value. e.g the following query:
MATCH (n:node)-[]->() return n, count(*)
returns the node alongside each of the counts. I would expect to be able to do something like this:
MATCH (n:node)-[]->() set n.relationCount = count(*)
However executing the above returns an error:
Aggregations should not be used like this.
I was looking through similar questions and although i didn't find the precise use of aggregates in setting data I did manage to reverse engineer an example into this:
MATCH (n:node)-[]->()
WITH n, count(*) as c
SET n.data = c
Which appears to work!

Neo4J Get only the first relationship per node

I have this graph where the nodes are researchers, and they are related by a relationship named R1, the relationship has a "value" property. How can I get the name of the researchers that are in the relationships with the greatest value? It's like get all the relationships order by r.value DESC but getting only the first relationship per researcher, because I don't want to see on the table duplicated researcher names. By the way, is there a way to get the name of the researchers order by the mean of their relationship "values"? Sorry about the confused topic, I don't speak English very well, thank you very much.
I've been trying things like the Cypher query bellow:
MATCH p=(n)-[r:R1]->(c)
WHERE id(n) < id(c) and r.coauthors = false
return DISTINCT n.name order by n.campus, r.value DESC
Correct me if I am wrong, but you want one result per "n" with the highest value from "r"?
MATCH (n)-[r:R1]->(c)
WHERE r.coauthors = false
WITH n, r ORDER BY r.value DESC
WITH n, head(collect(r)) AS highR
RETURN n.name, highR.value ORDER BY n.campus, highR.value DESC
This will get you all the r's in order and pick the first head(collect(r)) after first doing an ORDER BY. Then you just need to return the values you want. Check out Neo4j Aggregation Functions for some documentation on how aggregation functions work. Good luck!
As an aside, if there is a label that all "n" have, you should add that in your MATCH: MATCH (n:Person) .... it will help speed up your query!

Equivalent of row_number in neo4j

I'm trying to run a query where I assign integers based on the order they appeared in the query. I'd like it to work to the effect of:
MATCH users RETURN users ORDER BY created_at SET user.number=ROW_NUMBER()
Is there a way to do this in a single query? Thanks!
You can do it by playing a bit with a collection :
MATCH (n:User)
WITH n
ORDER BY n.created_at
WITH collect(n) as users
UNWIND range(0, size(users)-1) as pos
SET (users[pos]).number = pos

Find node with maximal (minimal) values of property in Neo4j

I have the following db:
CREATE (p1:Product {cost:10, name:'Hrundel'})
CREATE (p2:Product {cost:20, name:'Majora'})
CREATE (p3:Product {cost:30, name:'Elona'})
CREATE (s:Shop {name:'CarsMorpher'})
CREATE s-[:HAS]->(p1)
CREATE s-[:HAS]->(p2)
CREATE s-[:HAS]->(p3)
How can I find the name of the product that has lowest (highest) price?
Use max and min to calculate highest and lowest, and do something like this:
MATCH (p:Product)
WITH max(p.cost) as highestCost
MATCH (p2:Product)
where p2.cost=highestCost
return p2;
Using WITH you can chain the results from the earlier query together with a second query.
A different way of doing it:
MATCH (p:Product) RETURN p
ORDER BY p.cost DESC
LIMIT 1;
So this just lists them in descending order by price, and only gives you one (the maximum)

Returning a collection which has name property and repetition times

start n=node(22), p=node(1) match n<-[r1:FOLLOWS]-m-[r2:HAS]->k<-[r3:CONTAIN]-p return distinct [k.name]
I'm trying to return the names and repetition times of k values here and so far, I could not manage to do it. Is there a quick way to do it with cypher query?
Consider this example:
["Acting","Acting","Acting","Acting","Mongodb","Mongodb","Neo4j","Neo4j","Nursing"]
I'm trying to have something like:
[["Acting",4], ["Mongodb",2], ["Neo4j",2], ["Nursing",1]]
Note: The same names (property) indicate the same node.
Found it! :)
start n=node(22), p=node(1) match n<-[r1:FOLLOWS]-m-[r2:HAS]->k<-[r3:CONTAIN]-p return distinct [k.name] as skill, count(k) as count
And in case you ever want to further filter on the counts (say you only want results where the count is greater than 5, you could also wrap it in a WITH statement. Nice and tidy.
START n=node(22), p=node(1)
MATCH n<-[r1:FOLLOWS]-m-[r2:HAS]->k<-[r3:CONTAIN]-p
WITH distinct [k.name] as skill, count(k) as count
WHERE count > 5
RETURN skill, count

Resources