Neo4j Graph Algorithms Release — ANN, In memory graph improvements, Bug fixes

The latest releases of the Graph Algorithms Library add new functionality to the in memory graph.

Mark Needham
Neo4j Developer Blog


Over the last month or so we’ve released new functionality for the Neo4j Graph Algorithms Library, in versions, and


These releases see the following features and bug fixes:

  • support for loading multiple relationship types
  • support for loading multiple node and relationship properties
  • Cypher projections no longer write to the database
  • introduction of the Approximate Nearest Neighbors algorithm that I’ve previously written about.

Note that this release is only compatible with Neo4j 3.5.9 and above. You can read more about the release in the release notes.

You can install the latest release directly from the Neo4j Desktop in the ‘Plugins’ section of your project. Jennifer Reif also has a detailed post explaining how to install plugins if you haven’t used any yet.

Installing the Graph Algorithms Library

If you’re installing the library on a server installation of Neo4j you can download the JAR from the Neo4j Download Center.

Neo4j Download Center

Multiple relationship types

It’s now possible to load multiple relationship types into the in memory graph. Previous to this release, the in memory graph treated every relationship loaded as if it was of the same type.

Let’s see how to use this feature.

The following query creates an in memory graph for a Twitter dataset where we have User nodes connected by FOLLOWS and RETWEETED relationships:

CALL algo.graph.load('twitter', 
{direction: 'OUTGOING', concurrency: 8 })

We could now choose to run an algorithm using both these relationships, or just one of them. For example, the following query would compute the PageRank on our graph based on followers:

CALL algo.pageRank(null, 'FOLLOWS', {graph: 'twitter'})

And the following query would compute it based on the retweets that users have received:

CALL algo.pageRank(null, 'RETWEETED', {graph: 'twitter'})

Multiple properties on loaded graphs

It’s also possible to load multiple properties into the in memory graph for both nodes and relationships.

This feature is useful when we want to run the same algorithm multiple times with different configurations. The following query loads a transport graph with the node properties population and area:

CALL algo.graph.load('transport', 'City', '', {
graph: 'huge',
nodeProperties: {
population: 'population',
area: 'area'

We could run then run Label Propagation algorithm with weightProperty: 'population' if we want to bias label selection based on the population property:

CALL algo.beta.labelPropagation(null, null, {
graph: 'transport')

Or with weightProperty: 'area' if we want to bias label selection based on the area property:

CALL algo.beta.labelPropagation(null, null, {
graph: 'transport')

We can take a similar approach when loading relationship properties. We could then run the Weight PageRank algorithm or path finding algorithms with different configurations.

Cypher projections no longer write to the database

When creating in memory graphs from Cypher projections, it was possible to include write operations in those projection queries.

For example the following query would be valid, and would create one Person node per relationship:

'MATCH (n) RETURN id(n) AS id',
"MATCH (n)-->(m)
CREATE (:Person)
RETURN id(n) AS source, id(m) AS target",
{graph: "cypher"})

This would be a weird thing to do, but was possible. Not anymore! Now, if we write a Cypher query containing any write operations, we’ll get an error message like the following:

Failed to invoke procedure ``: Caused by: java.lang.IllegalArgumentException: Query must be read only. Query: [MATCH (n)-->(m) SET = 'foo' RETURN id(n) AS source, id(m) AS target]

We hope these changes improve your experience with the library, and if you have any questions or suggestions please send us an email to