Relationship operations

This section details the operations available over relationships and relationship properties stored in projected graphs within the Neo4j Graph Data Science library.

The graphs in the Neo4j Graph Data Science Library support properties for relationships. We provide multiple operations to work with the stored relationship-properties in projected graphs. Relationship properties are either created during the graph creation or when using the mutate mode of our graph algorithms.

To inspect stored relationship property values, the streamRelationshipProperties procedure can be used. This is useful if we ran multiple algorithms in mutate mode and want to retrieve some or all of the results.

To persist relationship types in a Neo4j database, we can use gds.graph.writeRelationship. Similar to streaming relationship properties, it is also possible to write back to Neo4j. This is similar to what an algorithm write execution mode does, but allows more fine-grained control over the operations. By default, no relationship properties will be written. To write relationship properties, these have to be explicitly specified.

We can also remove relationships from a named graph in the catalog. This is useful to free up main memory or to remove accidentally created relationship types.

1. Syntax

Syntax descriptions of the different operations over relationship types
CALL gds.graph.streamRelationshipProperty(
    graphName: String,
    relationshipProperties: List of String,
    relationshipTypes: List of Strings,
    configuration: Map
)
YIELD
    sourceNodeId: Integer,
    targetNodeId: Integer,
    relationshipType: String,
    propertyValue: Integer or Float
Table 1. Parameters
Name Type Optional Description

graphName

String

no

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

relationshipProperties

List of String

no

The relationship properties in the graph to stream.

relationshipTypes

List of Strings

yes

The relationship types to stream the relationship properties for graph.

configuration

Map

yes

Additional parameters to configure streamNodeProperties.

Table 2. Configuration
Name Type Default Description

concurrency

Integer

4

The number of concurrent threads. Note, this procedure is always running single-threaded.

Table 3. Results
Name Type Description

sourceNodeId

Integer

The id of the source node for the relationship.

targetNodeId

Integer

The id of the target node for the relationship.

relationshipType

Integer

The type of the relationship.

propertyValue

  • Integer

  • Float

The stored property value.

CALL gds.graph.streamRelationshipProperties(
    graphName: String,
    relationshipProperties: List of String,
    relationshipTypes: List of Strings,
    configuration: Map
)
YIELD
    sourceNodeId: Integer,
    targetNodeId: Integer,
    relationshipType: String,
    relationshipProperty: String,
    propertyValue: Integer or Float
Table 4. Parameters
Name Type Optional Description

graphName

String

no

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

relationshipProperties

List of String

no

The relationship properties in the graph to stream.

relationshipTypes

List of Strings

yes

The relationship types to stream the relationship properties for graph.

configuration

Map

yes

Additional parameters to configure streamNodeProperties.

Table 5. Configuration
Name Type Default Description

concurrency

Integer

4

The number of concurrent threads. Note, this procedure is always running single-threaded.

Table 6. Results
Name Type Description

sourceNodeId

Integer

The id of the source node for the relationship.

targetNodeId

Integer

The id of the target node for the relationship.

relationshipType

Integer

The type of the relationship.

relationshipProperty

Integer

The name of the relationship property.

propertyValue

  • Integer

  • Float

The stored property value.

CALL gds.graph.writeRelationship(
    graphName: String,
    relationshipType: String,
    relationshipProperty: String,
    configuration: Map
)
YIELD
  writeMillis: Integer,
  graphName: String,
  relationshipType: String,
  relationshipsWritten: Integer,
  relationshipProperty: String,
  propertiesWritten: Integer
Table 7. Parameters
Name Type Optional Description

graphName

String

no

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

relationshipType

String

no

The relationship type in the graph to write back.

relationshipProperty

String

yes

The relationship property to write back.

configuration

Map

yes

Additional parameters to configure writeRelationship.

Table 8. 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. Note, this procedure is always running single-threaded.

writeConcurrency

Integer

'concurrency'

The number of concurrent threads used for writing the relationship properties. Note, this procedure is always running single-threaded.

Table 9. Results
Name Type Description

writeMillis

Integer

Milliseconds for writing result data back to Neo4j.

graphName

String

The name of a graph stored in the catalog.

relationshipType

String

The type of the relationship that was written.

relationshipsWritten

Integer

Number relationships written.

relationshipProperty

String

The name of the relationship property that was written.

propertiesWritten

Integer

Number relationships properties written.

CALL gds.graph.deleteRelationships(
    graphName: String,
    relationshipType: String
)
YIELD
  graphName: String,
  relationshipType: String,
  deletedRelationships: Integer,
  deletedProperties: Map
Table 10. Parameters
Name Type Optional Description

graphName

String

no

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

relationshipType

String

no

The relationship type in the graph to remove.

Table 11. Results
Name Type Description

graphName

String

The name of a graph stored in the catalog.

relationshipType

String

The type of the removed relationships.

deletedRelationships

Integer

Number of removed relationships from the in-memory graph.

deletedProperties

Integer

Map where the key is the name of the relationship property, and the value is the number of removed properties under that name.

2. Examples

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

Visualization of the example graph
The following Cypher statement will create the example graph in the Neo4j database:
CREATE
  (alice:Person {name: 'Alice'}),
  (bob:Person {name: 'Bob'}),
  (carol:Person {name: 'Carol'}),
  (dave:Person {name: 'Dave'}),
  (eve:Person {name: 'Eve'}),
  (guitar:Instrument {name: 'Guitar'}),
  (synth:Instrument {name: 'Synthesizer'}),
  (bongos:Instrument {name: 'Bongos'}),
  (trumpet:Instrument {name: 'Trumpet'}),

  (alice)-[:LIKES { score: 5 }]->(guitar),
  (alice)-[:LIKES { score: 4 }]->(synth),
  (alice)-[:LIKES { score: 3, strength: 0.5}]->(bongos),
  (bob)-[:LIKES { score: 4 }]->(guitar),
  (bob)-[:LIKES { score: 5 }]->(synth),
  (carol)-[:LIKES { score: 2 }]->(bongos),
  (dave)-[:LIKES { score: 3 }]->(guitar),
  (dave)-[:LIKES { score: 1 }]->(synth),
  (dave)-[:LIKES { score: 5 }]->(bongos)
Project the graph:
CALL gds.graph.create(
  'personsAndInstruments',
  ['Person', 'Instrument'],         (1)
  {
    LIKES: {
      type: 'LIKES',                (2)
      properties: {
        strength: {                 (3)
          property: 'strength',
          defaultValue: 1.0
        },
        score: {
          property: 'score'         (4)
        }
      }
    }
  }
)
1 Project node labels Person and Instrument.
2 Project relationship type LIKES.
3 Project property strength of relationship type LIKES setting a default value of 1.0 because not all relationships have that property.
4 Project property score of relationship type LIKES.
Compute the Node Similarity in our graph:
CALL gds.nodeSimilarity.mutate('personsAndInstruments', {   (1)
  mutateRelationshipType: 'SIMILAR',                        (2)
  mutateProperty: 'score'                                   (3)
})
1 Run NodeSimilarity in mutate mode on personsAndInstruments projected graph.
2 The algorithm will create relationships of type SIMILAR in the projected graph.
3 The algorithm will create relationship property score for each created relationship.

2.1. Stream

2.1.1. Single property

The most basic case for streaming relationship information from a named graph is a single property. In the example below we stream the relationship property score.

Stream a single relationship property:
CALL gds.graph.streamRelationshipProperty(
  'personsAndInstruments',                  (1)
  'score'                                   (2)
)
YIELD
  sourceNodeId, targetNodeId, relationshipType, propertyValue
RETURN
  gds.util.asNode(sourceNodeId).name as source, gds.util.asNode(targetNodeId).name as target, relationshipType, propertyValue
ORDER BY source ASC, target ASC
1 The name of the projected graph.
2 The property we want to stream out.
Table 12. Results
source target relationshipType propertyValue

"Alice"

"Bob"

"SIMILAR"

0.6666666666666666

"Alice"

"Bongos"

"LIKES"

3.0

"Alice"

"Carol"

"SIMILAR"

0.3333333333333333

"Alice"

"Dave"

"SIMILAR"

1.0

"Alice"

"Guitar"

"LIKES"

5.0

"Alice"

"Synthesizer"

"LIKES"

4.0

"Bob"

"Alice"

"SIMILAR"

0.6666666666666666

"Bob"

"Dave"

"SIMILAR"

0.6666666666666666

"Bob"

"Guitar"

"LIKES"

4.0

"Bob"

"Synthesizer"

"LIKES"

5.0

"Carol"

"Alice"

"SIMILAR"

0.3333333333333333

"Carol"

"Bongos"

"LIKES"

2.0

"Carol"

"Dave"

"SIMILAR"

0.3333333333333333

"Dave"

"Alice"

"SIMILAR"

1.0

"Dave"

"Bob"

"SIMILAR"

0.6666666666666666

"Dave"

"Bongos"

"LIKES"

5.0

"Dave"

"Carol"

"SIMILAR"

0.3333333333333333

"Dave"

"Guitar"

"LIKES"

3.0

"Dave"

"Synthesizer"

"LIKES"

1.0

As we can see from the results, we get two relationship types (SIMILAR and LIKES) that have the score relationship property. We can further on filter the relationship types we want to stream, this is demonstrated in the next example.

Stream a single relationship property for specific relationship type:
CALL gds.graph.streamRelationshipProperty(
  'personsAndInstruments',                  (1)
  'score',                                  (2)
  ['SIMILAR']                               (3)
)
YIELD
  sourceNodeId, targetNodeId, relationshipType, propertyValue
RETURN
  gds.util.asNode(sourceNodeId).name as source, gds.util.asNode(targetNodeId).name as target, relationshipType, propertyValue
ORDER BY source ASC, target ASC
1 The name of the projected graph.
2 The property we want to stream out.
3 List of relationship types we want to stream the property from, only use the ones we need.
Table 13. Results
source target relationshipType propertyValue

"Alice"

"Bob"

"SIMILAR"

0.6666666666666666

"Alice"

"Carol"

"SIMILAR"

0.3333333333333333

"Alice"

"Dave"

"SIMILAR"

1.0

"Bob"

"Alice"

"SIMILAR"

0.6666666666666666

"Bob"

"Dave"

"SIMILAR"

0.6666666666666666

"Carol"

"Alice"

"SIMILAR"

0.3333333333333333

"Carol"

"Dave"

"SIMILAR"

0.3333333333333333

"Dave"

"Alice"

"SIMILAR"

1.0

"Dave"

"Bob"

"SIMILAR"

0.6666666666666666

"Dave"

"Carol"

"SIMILAR"

0.3333333333333333

2.1.2. Multiple properties

It is also possible to stream multiple relationship properties.

Stream multiple relationship properties:
CALL gds.graph.streamRelationshipProperties(
  'personsAndInstruments',                      (1)
  ['score', 'strength'],                        (2)
  ['LIKES']                                     (3)
)
YIELD
  sourceNodeId, targetNodeId, relationshipType, relationshipProperty, propertyValue
RETURN
  gds.util.asNode(sourceNodeId).name as source, gds.util.asNode(targetNodeId).name as target, relationshipType, relationshipProperty, propertyValue
ORDER BY source ASC, target ASC
1 The name of the projected graph.
2 List of properties we want to stream out, allows us to stream more than one property.
3 List of relationship types we want to stream the property from, only use the ones we need.
Table 14. Results
source target relationshipType relationshipProperty propertyValue

"Alice"

"Bongos"

"LIKES"

"score"

3.0

"Alice"

"Bongos"

"LIKES"

"strength"

0.5

"Alice"

"Guitar"

"LIKES"

"score"

5.0

"Alice"

"Guitar"

"LIKES"

"strength"

1.0

"Alice"

"Synthesizer"

"LIKES"

"score"

4.0

"Alice"

"Synthesizer"

"LIKES"

"strength"

1.0

"Bob"

"Guitar"

"LIKES"

"score"

4.0

"Bob"

"Guitar"

"LIKES"

"strength"

1.0

"Bob"

"Synthesizer"

"LIKES"

"score"

5.0

"Bob"

"Synthesizer"

"LIKES"

"strength"

1.0

"Carol"

"Bongos"

"LIKES"

"score"

2.0

"Carol"

"Bongos"

"LIKES"

"strength"

1.0

"Dave"

"Bongos"

"LIKES"

"score"

5.0

"Dave"

"Bongos"

"LIKES"

"strength"

1.0

"Dave"

"Guitar"

"LIKES"

"score"

3.0

"Dave"

"Guitar"

"LIKES"

"strength"

1.0

"Dave"

"Synthesizer"

"LIKES"

"score"

1.0

"Dave"

"Synthesizer"

"LIKES"

"strength"

1.0

2.1.3. Multiple relationship types

Similar to the multiple relationship properties we can stream properties for multiple relationship types.

Stream relationship properties of a multiple relationship projections:
CALL gds.graph.streamRelationshipProperties(
  'personsAndInstruments',                          (1)
  ['score'],                                        (2)
  ['LIKES', 'SIMILAR']                              (3)
)
YIELD
  sourceNodeId, targetNodeId, relationshipType, relationshipProperty, propertyValue
RETURN
  gds.util.asNode(sourceNodeId).name as source,     (4)
  gds.util.asNode(targetNodeId).name as target,     (5)
  relationshipType,
  relationshipProperty,
  propertyValue
ORDER BY source ASC, target ASC
1 The name of the projected graph.
2 List of properties we want to stream out, allows us to stream more than one property.
3 List of relationship types we want to stream the property from, only use the ones we need.
4 Return the name of the source node.
5 Return the name of the target node.
Table 15. Results
source target relationshipType relationshipProperty propertyValue

"Alice"

"Bob"

"SIMILAR"

"score"

0.6666666666666666

"Alice"

"Bongos"

"LIKES"

"score"

3.0

"Alice"

"Carol"

"SIMILAR"

"score"

0.3333333333333333

"Alice"

"Dave"

"SIMILAR"

"score"

1.0

"Alice"

"Guitar"

"LIKES"

"score"

5.0

"Alice"

"Synthesizer"

"LIKES"

"score"

4.0

"Bob"

"Alice"

"SIMILAR"

"score"

0.6666666666666666

"Bob"

"Dave"

"SIMILAR"

"score"

0.6666666666666666

"Bob"

"Guitar"

"LIKES"

"score"

4.0

"Bob"

"Synthesizer"

"LIKES"

"score"

5.0

"Carol"

"Alice"

"SIMILAR"

"score"

0.3333333333333333

"Carol"

"Bongos"

"LIKES"

"score"

2.0

"Carol"

"Dave"

"SIMILAR"

"score"

0.3333333333333333

"Dave"

"Alice"

"SIMILAR"

"score"

1.0

"Dave"

"Bob"

"SIMILAR"

"score"

0.6666666666666666

"Dave"

"Bongos"

"LIKES"

"score"

5.0

"Dave"

"Carol"

"SIMILAR"

"score"

0.3333333333333333

"Dave"

"Guitar"

"LIKES"

"score"

3.0

"Dave"

"Synthesizer"

"LIKES"

"score"

1.0

The properties we want to stream must exist for each specified relationship type.

2.2. Write

We can write relationships stored in a named in-memory graph back to Neo4j. This can be used to write algorithm results (for example from Node Similarity) or relationships that have been aggregated during graph creation.

The relationships to write are specified by a relationship type.

Relationships are always written using a single thread.

2.2.1. Relationship type

Write relationships to Neo4j:
CALL gds.graph.writeRelationship(
  'personsAndInstruments',        (1)
  'SIMILAR'                       (2)
)
YIELD
  graphName, relationshipType, relationshipProperty, relationshipsWritten, propertiesWritten
1 The name of the projected graph.
2 The relationship type we want to write back to the Neo4j database.
Table 16. Results
graphName relationshipType relationshipProperty relationshipsWritten propertiesWritten

"personsAndInstruments"

"SIMILAR"

null

10

0

By default, no relationship properties will be written, as it can be seen from the results, the relationshipProperty value is null and propertiesWritten are 0.

Here is an illustration of how the example graph looks in Neo4j after executing the example above.

Visualization of the example graph after writing relationships back

The SIMILAR relationships have been added to the underlying database and can be used in Cypher queries or for projecting to in-memory graph for running algorithms. The relationships in this example are undirected because we used Node Similarity to mutate the in-memory graph and this algorithm creates undirected relationships, this may not be the case if we use different algorithms.

2.2.2. Relationship type with property

To write relationship properties, these have to be explicitly specified.

Write relationships and their properties to Neo4j:
CALL gds.graph.writeRelationship(
  'personsAndInstruments',          (1)
  'SIMILAR',                        (2)
  'score'                           (3)
)
YIELD
  graphName, relationshipType, relationshipProperty, relationshipsWritten, propertiesWritten
1 The name of the projected graph.
2 The relationship type we want to write back to the Neo4j database.
3 The property name of the relationship we want to write back to the Neo4j database.
Table 17. Results
graphName relationshipType relationshipProperty relationshipsWritten propertiesWritten

"personsAndInstruments"

"SIMILAR"

"score"

10

10

2.3. Delete

We can delete all relationships of a given type from a named graph in the catalog. This is useful to free up main memory or to remove accidentally created relationship types.

Deleting relationships of a given type is only possible if it is not the last relationship type present in the graph. If we still want to delete these relationships we need to drop the graph instead.

Delete all relationships of type SIMILAR from a named graph:
CALL gds.graph.deleteRelationships(
  'personsAndInstruments',            (1)
  'SIMILAR'                           (2)
)
YIELD
  graphName, relationshipType, deletedRelationships, deletedProperties
1 The name of the projected graph.
2 The relationship type we want to delete from the projected graph.
Table 18. Results
graphName relationshipType deletedRelationships deletedProperties

"personsAndInstruments"

"SIMILAR"

10

{score=10}