Streaming relationships

To inspect the relationship topology only, the gds.graph.relationships.stream procedure can be used. To inspect stored relationship property values, the relationshipProperties.stream 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.

Syntax

Syntax descriptions of the different streaming options over relationships
CALL gds.graph.relationships.stream(
    graphName: String,
    relationshipTypes: List of Strings,
    configuration: Map
)
YIELD
    sourceNodeId: Integer,
    targetNodeId: Integer,
    relationshipType: String
Table 1. Parameters
Name Type Optional Description

graphName

String

no

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

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.

CALL gds.graph.relationshipProperty.stream(
    graphName: String,
    relationshipProperty: String,
    relationshipTypes: List of Strings,
    configuration: Map
)
YIELD
    sourceNodeId: Integer,
    targetNodeId: Integer,
    relationshipType: 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.

relationshipProperty

String

no

The relationship property 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.

propertyValue

  • Integer

  • Float

The stored property value.

CALL gds.graph.relationshipProperties.stream(
    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 7. 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 8. Configuration
Name Type Default Description

concurrency

Integer

4

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

Table 9. 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.

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 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.project(
  '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 add relationships of type SIMILAR to the projected graph.
3 The algorithm will add relationship property score for each added relationship.

Topology

The most basic case for streaming relationship information from a named graph is streaming its topology. In this example below we stream relationship topology for all relationship types, represented by source, target and relationship type.

Stream all relationships:
CALL gds.graph.relationships.stream(
  'personsAndInstruments'                  (1)
)
YIELD
  sourceNodeId, targetNodeId, relationshipType
RETURN
  gds.util.asNode(sourceNodeId).name as source, gds.util.asNode(targetNodeId).name as target, relationshipType
ORDER BY source ASC, target ASC
1 The name of the projected graph.
Table 10. Results
source target relationshipType

"Alice"

"Bob"

"SIMILAR"

"Alice"

"Bongos"

"LIKES"

"Alice"

"Carol"

"SIMILAR"

"Alice"

"Dave"

"SIMILAR"

"Alice"

"Guitar"

"LIKES"

"Alice"

"Synthesizer"

"LIKES"

"Bob"

"Alice"

"SIMILAR"

"Bob"

"Dave"

"SIMILAR"

"Bob"

"Guitar"

"LIKES"

"Bob"

"Synthesizer"

"LIKES"

"Carol"

"Alice"

"SIMILAR"

"Carol"

"Bongos"

"LIKES"

"Carol"

"Dave"

"SIMILAR"

"Dave"

"Alice"

"SIMILAR"

"Dave"

"Bob"

"SIMILAR"

"Dave"

"Bongos"

"LIKES"

"Dave"

"Carol"

"SIMILAR"

"Dave"

"Guitar"

"LIKES"

"Dave"

"Synthesizer"

"LIKES"

As we can see from the results, we get two relationship types (SIMILAR and LIKES). We can further on filter the relationship types we want to stream. This can be achieved by passing a second argument to the procedure as demonstrated in the next example.

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

"Alice"

"Bob"

"SIMILAR"

"Alice"

"Carol"

"SIMILAR"

"Alice"

"Dave"

"SIMILAR"

"Bob"

"Alice"

"SIMILAR"

"Bob"

"Dave"

"SIMILAR"

"Carol"

"Alice"

"SIMILAR"

"Carol"

"Dave"

"SIMILAR"

"Dave"

"Alice"

"SIMILAR"

"Dave"

"Bob"

"SIMILAR"

"Dave"

"Carol"

"SIMILAR"

Single property

The most basic case for streaming relationship properties 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.relationshipProperty.stream(
  '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.relationshipProperty.stream(
  '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

Multiple properties

It is also possible to stream multiple relationship properties.

Stream multiple relationship properties:
CALL gds.graph.relationshipProperties.stream(
  '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

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.relationshipProperties.stream(
  '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.