Adding node labels

Adding node labels to the graph after the creation can be used to create labels based on f.i. algorithm results. As with existing labels, they allow filtering the graph on following operations.

Syntax

CALL gds.graph.nodeLabel.mutate(
    graphName: String,
    nodeLabel: String,
    configuration: Map
)
YIELD
    mutateMillis: Integer,
    graphName: String,
    nodeLabel: String,
    nodeLabelsWritten: Integer,
    nodeCount: Integer,
    configuration: Map
Table 1. 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 2. 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. 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

mutateMillis

Integer

Milliseconds for writing result data back to the in-memory graph.

nodeLabel

String

The name of the label that was added to the in-memory graph.

nodeLabelsWritten

Integer

Number of node labels written.

graphName

String

The name of a graph stored in the catalog.

nodeCount

Integer

The total number of nodes in the graph.

configuration

Map

The configuration used to run the procedure.

Example

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.

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:
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)
  }
)
Compute the Degree Centrality in our social graph:
CALL gds.degree.mutate('socialGraph', {mutateProperty: 'score'})

To mutate the in-memory graph by adding a new node label for nodes with score higher than 0, we use the following query:

Add the Reader node label to the in-memory graph:
CALL gds.graph.nodeLabel.mutate('socialGraph', 'Reader', { nodeFilter: 'n.score > 0.0' })
YIELD graphName, nodeLabel, nodeLabelsWritten, nodeCount
Table 4. Results
graphName nodeLabel nodeLabelsWritten nodeCount

"socialGraph"

"Reader"

2

4

As we can see from the result there were two nodes that matched the specified filter and they received the node label Reader. We can inspect the result by streaming back the score property of the Reader node label, we can do that using the following query:

Stream the score property for Reader nodes:
CALL gds.graph.nodeProperty.stream('socialGraph', 'score', ['Reader'])
YIELD nodeId, propertyValue
RETURN gds.util.asNode(nodeId).name AS name, propertyValue AS score
ORDER BY score DESC
Table 5. Results
name score

"Florentin"

2.0

"Adam"

1.0

We can see that Veselin has not been labelled as a Reader because the score property for that node is 0.