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
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,
configuration: Map
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: |
nodeLabels |
String or List of Strings |
yes |
The node labels to write back their node properties. |
configuration |
Map |
yes |
Additional parameters to configure writeNodeProperties. |
Name | Type | Default | Description |
---|---|---|---|
concurrency |
Integer |
4 |
The number of concurrent threads used for running the procedure. Also provides the default value for |
writeConcurrency |
Integer |
'concurrency' |
The number of concurrent threads used for writing the node properties. |
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. |
configuration |
Map |
The configuration used to run the procedure. |
CALL gds.graph.nodeLabel.write(
graphName: String,
nodeLabel: String,
configuration: Map
)
YIELD
writeMillis: Integer,
nodeLabelsWritten: Integer,
nodeLabel: String,
graphName: String,
nodeCount: Integer,
configuration: Map
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. |
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. |
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. The examples use Cypher projections as the norm. Native projections will be deprecated in a future release. |
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.
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)
MATCH (n:Person)-[r:KNOWS|READ]->(m:Person|Book)
RETURN gds.graph.project('socialGraph', n, m,
{
sourceNodeLabels: labels(n),
targetNodeLabels: labels(m),
sourceNodeProperties: n { .age },
targetNodeProperties: CASE WHEN m:Person THEN m { .age } ELSE {} END,
relationshipType: type(r)
}
)
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:
score
property back to Neo4j:CALL gds.graph.nodeProperties.write('socialGraph', ['score'])
YIELD propertiesWritten
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.
age
and score
properties back to Neo4j with a new name for score
:CALL gds.graph.nodeProperties.write('socialGraph', ['age', {score: 'writtenScore'}])
YIELD nodeProperties
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.
CALL gds.graph.nodeProperties.write('socialGraph', ['score'], ['Person'])
YIELD propertiesWritten
propertiesWritten |
---|
3 |
If the |
Write Node Label
To write a new node label to the database for nodes with score higher than 0
, we use the following query:
Reader
node label back to Neo4j:CALL gds.graph.nodeLabel.write('socialGraph', 'Reader', { nodeFilter: 'n.score > 0.0' })
YIELD graphName, nodeCount, nodeLabel, nodeLabelsWritten
graphName | nodeCount | nodeLabel | nodeLabelsWritten |
---|---|---|---|
"socialGraph" |
4 |
"Reader" |
2 |
Reader
node label:MATCH (n:Reader) RETURN n.name AS name, labels(n) AS labels
ORDER BY name ASC
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
.