Writing node properties and labels

It is possible to persist computed node properties into a Neo4j database. We refer to this operation as writing. This is similar to what an algorithm write execution mode does, but allows more fine-grained control over the operations.

Syntax

Syntax descriptions of the different operations over node properties
CALL gds.graph.nodeProperties.write(
    graphName: String,
    nodeProperties: String or Map of Strings or List of Strings and/or Maps of Strings,
    nodeLabels: String or List of Strings,
    configuration: Map
)
YIELD
    writeMillis: Integer,
    propertiesWritten: Integer,
    graphName: String,
    nodeProperties: String or List of String
Table 1. Parameters
Name Type Optional Description

graphName

String

no

The name under which the graph is stored in the catalog.

nodeProperties

String, Map of Strings, or List of Strings and/or Maps of Strings

no

The node properties in the graph to write back. To write back properties with new custom names, store them as entries inside maps in the form: nodeProperty: 'renamedProperty'.

nodeLabels

String or List of Strings

yes

The node labels to write back their node properties.

configuration

Map

yes

Additional parameters to configure writeNodeProperties.

Table 2. Configuration
Name Type Default Description

concurrency

Integer

4

The number of concurrent threads used for running the procedure. Also provides the default value for writeConcurrency

writeConcurrency

Integer

'concurrency'

The number of concurrent threads used for writing the node properties.

Table 3. Results
Name Type Description

writeMillis

Integer

Milliseconds for writing result data back to Neo4j.

propertiesWritten

Integer

Number of properties written.

graphName

String

The name of a graph stored in the catalog.

nodeProperties

String or List of String

The written node properties.

CALL gds.graph.nodeLabel.write(
    graphName: String,
    nodeLabel: String,
    configuration: Map
)
YIELD
    writeMillis: Integer,
    nodeLabelsWritten: Integer,
    nodeLabel: String,
    graphName: String,
    nodeCount: Integer,
    configuration: Map
Table 4. Parameters
Name Type Optional Description

graphName

String

no

The name under which the graph is stored in the catalog.

nodeLabel

String

no

The node label to write back.

configuration

Map

yes

Additional parameters to configure writeNodeProperties.

Table 5. Configuration
Name Type Default Description

nodeFilter

String

n/a

A Cypher predicate for filtering nodes in the input graph. See Projecting a subgraph.

concurrency

Integer

4

The number of concurrent threads used for running the procedure.

Table 6. Results
Name Type Description

writeMillis

Integer

Milliseconds for writing result data back to Neo4j.

nodeLabelsWritten

Integer

Number of node labels written.

graphName

String

The name of a graph stored in the catalog.

nodeLabel

String

The written node label.

nodeCount

Integer

The total number of nodes in the graph.

configuration

Map

The configuration used to run the procedure.

Examples

All the examples below should be run in an empty database.

In order to demonstrate the GDS capabilities over node properties, we are going to create a small social network graph in Neo4j and project it into our graph catalog.

The following Cypher statement will create the example graph in the Neo4j database:
CREATE
  (florentin:Person { name: 'Florentin', age: 16 }),
  (adam:Person { name: 'Adam', age: 18 }),
  (veselin:Person { name: 'Veselin', age: 20 }),
  (hobbit:Book { name: 'The Hobbit', numberOfPages: 310 }),
  (florentin)-[:KNOWS { since: 2010 }]->(adam),
  (florentin)-[:KNOWS { since: 2018 }]->(veselin),
  (adam)-[:READ]->(hobbit)
Project the small social network graph:
CALL gds.graph.project(
  'socialGraph',
  {
    Person: {properties: "age"},
    Book: {}
  },
  ['KNOWS', 'READ']
)
Compute the Degree Centrality in our social graph:
CALL gds.degree.mutate('socialGraph', {mutateProperty: 'score'})

Write node properties

To write the 'score' property for all node labels in the social graph, we use the following query:

Write the score property back to Neo4j:
CALL gds.graph.nodeProperties.write('socialGraph', ['score'])
YIELD propertiesWritten
Table 7. Results
propertiesWritten

4

The above example requires the score property to be present on at least one projected node label, and the properties will be written for all such labels.

Renaming properties when writing back

It is possible to rename node properties and write them back to the database under a custom name. For this, you can use a map where each entry is a tuple {nodeProperty: 'renamedProperty'} i.e., the key corresponds to an existing node property in the in-memory graph and the value corresponds to the name to be written back to the database.

For convenience, a map may hold more than one entries. The nodeProperties configuration parameter accepts both strings and maps and any combination of the two inside a list. This can be helpful when we only want to rename a handful of properties.

Write the age and score properties back to Neo4j with a new name for score:
CALL gds.graph.nodeProperties.write('socialGraph', ['age', {score: 'writtenScore'}])
YIELD nodeProperties
Table 8. Results
nodeProperties

[age, writtenScore]

In the above example, we write age back to the database with its default name whereas we renamed score to writtenScore by using a map.

NodeLabels

The procedure can be configured to write just the properties for some specific node labels. In the following example, we will only write back the scores of the Person nodes.

Write node properties of a specific projected node label to Neo4j:
CALL gds.graph.nodeProperties.write('socialGraph', ['score'], ['Person'])
YIELD propertiesWritten
Table 9. Results
propertiesWritten

3

If the nodeLabels parameter is specified, it is required that all given node labels have all of the given properties.

Write Node Label

To write a new node label to the database for nodes with score higher than 0, we use the following query:

Write the Reader node label back to Neo4j:
CALL gds.graph.nodeLabel.write('socialGraph', 'Reader', { nodeFilter: 'n.score > 0.0' })
YIELD graphName, nodeCount, nodeLabel, nodeLabelsWritten
Table 10. Results
graphName nodeCount nodeLabel nodeLabelsWritten

"socialGraph"

4

"Reader"

2

Query the Reader node label:
MATCH (n:Reader) RETURN n.name AS name, labels(n) AS labels
ORDER BY name ASC
Table 11. Results
name labels

"Adam"

[Person, Reader]

"Florentin"

[Person, Reader]

As we can see from the database Veselin who has score: 0.0 is not a Reader.