Streaming nodes
To inspect property values on nodes in GDS graphs, the gds.graph.nodeProperties.stream
procedure can be used.
This is useful if we have run multiple algorithms in mutate
mode and want to retrieve some or all of the results.
Syntax
CALL gds.graph.nodeProperty.stream(
graphName: String,
nodeProperties: String,
nodeLabels: String or List of Strings,
configuration: Map
)
YIELD
nodeId: Integer,
propertyValue: Integer or Float or List of Integer or List of Float,
nodeLabels: List of Strings
Name | Type | Optional | Description |
---|---|---|---|
graphName |
String |
no |
The name under which the graph is stored in the catalog. |
nodeProperties |
String |
no |
The node property in the graph to stream. |
nodeLabels |
String or List of Strings |
yes |
The node labels to stream the node properties for graph. |
configuration |
Map |
yes |
Additional parameters to configure streamNodeProperties. |
Name | Type | Default | Description |
---|---|---|---|
concurrency |
Integer |
4 |
The number of concurrent threads. Note, this procedure is always running single-threaded. |
listNodeLabels |
Boolean |
false |
Whether to return a list of node labels for each node. |
Name | Type | Description |
---|---|---|
nodeId |
Integer |
The id of the node. |
propertyValue |
|
The stored property value. |
nodeLabels |
List of Strings |
The node labels of the node. |
CALL gds.graph.nodeProperties.stream(
graphName: String,
nodeProperties: String or List of Strings,
nodeLabels: String or List of Strings,
configuration: Map
)
YIELD
nodeId: Integer,
nodeProperty: String,
propertyValue: Integer or Float or List of Integer or List of Float,
nodeLabels: List of Strings
Name | Type | Optional | Description |
---|---|---|---|
graphName |
String |
no |
The name under which the graph is stored in the catalog. |
nodeProperties |
String or List of Strings |
no |
The node properties in the graph to stream. |
nodeLabels |
String or List of Strings |
yes |
The node labels to stream the node properties for graph. |
configuration |
Map |
yes |
Additional parameters to configure streamNodeProperties. |
Name | Type | Default | Description |
---|---|---|---|
concurrency |
Integer |
4 |
The number of concurrent threads. Note, this procedure is always running single-threaded. |
listNodeLabels |
Boolean |
false |
Whether to return a list of node labels for each node. |
Name | Type | Description |
---|---|---|
nodeId |
Integer |
The id of the node. |
nodeProperty |
String |
The name of the node property. |
propertyValue |
|
The stored property value. |
nodeLabels |
List of Strings |
The node labels of the node. |
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 of streaming 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'})
We can stream node properties stored in a named in-memory graph back to the user.
This is useful if we ran multiple algorithms in mutate
mode and want to retrieve some or all of the results.
This is similar to what an algorithm stream
execution mode does, but allows more fine-grained control over the operations.
Single property
In the following, we stream the previously computed scores score
.
score
node property:CALL gds.graph.nodeProperty.stream('socialGraph', 'score')
YIELD nodeId, propertyValue
RETURN gds.util.asNode(nodeId).name AS name, propertyValue AS score
ORDER BY score DESC
name | score |
---|---|
"Florentin" |
2.0 |
"Adam" |
1.0 |
"Veselin" |
0.0 |
"The Hobbit" |
0.0 |
The above example requires all given properties to be present on at least one node projection, and the properties will be streamed for all such projections. |
NodeLabels
The procedure can be configured to stream just the properties for specific node labels.
score
property for Person
nodes:CALL gds.graph.nodeProperty.stream('socialGraph', 'score', ['Person'])
YIELD nodeId, propertyValue
RETURN gds.util.asNode(nodeId).name AS name, propertyValue AS score
ORDER BY score DESC
name | score |
---|---|
"Florentin" |
2.0 |
"Adam" |
1.0 |
"Veselin" |
0.0 |
It is required, that all specified node labels have the node property.
Multiple Properties
We can also stream several properties at once.
CALL gds.graph.nodeProperties.stream('socialGraph', ['score', 'age'])
YIELD nodeId, nodeProperty, propertyValue
RETURN gds.util.asNode(nodeId).name AS name, nodeProperty, propertyValue
ORDER BY name, nodeProperty
name | nodeProperty | propertyValue |
---|---|---|
"Adam" |
"age" |
18 |
"Adam" |
"score" |
1.0 |
"Florentin" |
"age" |
16 |
"Florentin" |
"score" |
2.0 |
"Veselin" |
"age" |
20 |
"Veselin" |
"score" |
0.0 |
When streaming multiple node properties, the name of each property is included in the result. This adds with some overhead, as each property name must be repeated for each node in the result, but is necessary in order to distinguish properties. |
Additionally, when streaming one or more node properties, we can also return the node labels for each individual node by setting the listNodeLabels
configuration option.
CALL gds.graph.nodeProperties.stream(
'socialGraph',
['score'],
['*'],
{ listNodeLabels: true }
)
YIELD nodeId, nodeProperty, propertyValue, nodeLabels
RETURN
gds.util.asNode(nodeId).name AS name,
nodeProperty,
propertyValue,
nodeLabels
name | nodeProperty | propertyValue | nodeLabels |
---|---|---|---|
"Florentin" |
"score" |
2.0 |
["Person"] |
"Adam" |
"score" |
1.0 |
["Person"] |
"Veselin" |
"score" |
0.0 |
["Person"] |
"The Hobbit" |
"score" |
0.0 |
["Book"] |
Single node property access
GDS offers a function to access the property value of a specific node from an in-memory graph directly in a Cypher query.
Syntax
gds.util.nodeProperty(
graphName: String,
nodeId: Node or Integer,
propertyKey: String,
nodeLabel: String
)
Name | Type | Optional | Description |
---|---|---|---|
graphName |
String |
no |
Name of the graph in the catalog. |
nodeId |
Integer |
no |
Id of the node. |
propertyKey |
String |
no |
Property key to access. |
nodeLabel |
String |
yes |
Label on the node. |
If the property value is missing for the given node, null
is returned.
Examples
We use the socialGraph
with the property score
introduced above.
MATCH (florentin:Person {name: 'Florentin'})
RETURN
florentin.name AS name,
gds.util.nodeProperty('socialGraph', florentin, 'score') AS score
name | score |
---|---|
"Florentin" |
2.0 |