Skip to content

Instantly share code, notes, and snippets.

@jexp
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jexp/9362989 to your computer and use it in GitHub Desktop.
Save jexp/9362989 to your computer and use it in GitHub Desktop.
Shows how to order by a random value in Neo4j's Cypher

Random Thoughts

There was a question on the Neo4j Google Group about returning results in a random order in Cypher.

CREATE (Neo:Crew { name:'Neo' }),
  (Morpheus:Crew { name: 'Morpheus' }),
 (Trinity:Crew { name: 'Trinity' }),
 (Cypher:Crew:Matrix { name: 'Cypher' }),
 (Smith:Matrix { name: 'Agent Smith' }),
 (Architect:Matrix { name:'The Architect'}),
 (Neo)-[:KNOWS]->(Morpheus),(Neo)-[:LOVES]->(Trinity),
 (Morpheus)-[:KNOWS]->(Trinity),(Morpheus)-[:KNOWS]->(Cypher),
 (Cypher)-[:KNOWS]->(Smith),(Smith)-[:CODED_BY]->(Architect)

First Try

The naive approach is just to order by rand():

MATCH (n:Crew)
RETURN n
ORDER BY rand()

Which fails with:

ORDER BY expressions must be deterministic. For instance, you cannot use the rand() function in the expression

That’s explainable, how would you order by something that generates a new value on each call.

Working Query

So we have to associate a random value with each row. Fortunately that’s easy with WITH:

MATCH (n:Crew)
WITH n, rand() AS r
ORDER BY r
RETURN n

So WITH n, rand() as r adds a new column called r (we need the alias) to each row, then we can order by that as part of with (we could even paginate) but in the RETURN clause we only return n and don’t expose r.

This approach is also handy if you want to order by things that you don’t want to expose later on.

Useful concept

Like ordering by the name of the person, but returning the friends in that order:

MATCH (n:Crew)-[:KNOWS]->(o)
WITH n.name as name, o
ORDER BY name DESC
RETURN o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment