写入节点属性和标签

可以将计算出的节点属性持久化到 Neo4j 数据库中。我们将此操作称为写入 (writing)。这类似于算法的 write 执行模式,但允许对操作进行更细粒度的控制。

语法

节点属性不同操作的语法说明
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
表 1. 参数
名称 类型 可选 描述

graphName

字符串

图在目录中存储时所使用的名称。

nodeProperties

字符串、字符串映射,或字符串和/或字符串映射的列表

要写回图中的节点属性。要使用新的自定义名称写回属性,请将其存储在形式为 nodeProperty: 'renamedProperty' 的映射条目中。

nodeLabels

字符串或字符串列表

要写回其节点属性的节点标签。

配置

Map

用于配置 writeNodeProperties 的附加参数。

表 2. 配置
名称 类型 默认 可选 描述

concurrency

整数

4 [1]

用于运行算法的并发线程数。

writeConcurrency

整数

'concurrency'

用于写入节点属性的并发线程数。

1. 在 GDS 会话 中,默认值为可用处理器数量。

表 3. 结果
名称 类型 描述

writeMillis

整数

将结果数据写回 Neo4j 的毫秒数。

propertiesWritten

整数

已写入的属性数量。

graphName

字符串

存储在目录中的图的名称。

nodeProperties

字符串或字符串列表

已写入的节点属性。

配置

Map

运行该过程所使用的配置。

CALL gds.graph.nodeLabel.write(
    graphName: String,
    nodeLabel: String,
    configuration: Map
)
YIELD
    writeMillis: Integer,
    nodeLabelsWritten: Integer,
    nodeLabel: String,
    graphName: String,
    nodeCount: Integer,
    configuration: Map
表 4. 参数
名称 类型 可选 描述

graphName

字符串

图在目录中存储时所使用的名称。

nodeLabel

字符串

要写回的节点标签。

配置

Map

用于配置 writeNodeProperties 的附加参数。

表 5. 配置
名称 类型 默认 可选 描述

nodeFilter (节点过滤器)

字符串

不适用

用于过滤输入图中节点的 Cypher 谓词。请参阅 投影子图

concurrency

整数

4 [2]

用于运行算法的并发线程数。

2. 在 GDS 会话 中,默认值为可用处理器数量。

表 6. 结果
名称 类型 描述

writeMillis

整数

将结果数据写回 Neo4j 的毫秒数。

nodeLabelsWritten

整数

已写入的节点标签数量。

graphName

字符串

存储在目录中的图的名称。

nodeLabel

字符串

已写入的节点标签。

nodeCount

整数

图中节点的总数。

配置

Map

运行该过程所使用的配置。

示例

以下所有示例应在空数据库中运行。

本示例将 Cypher 投影作为标准。原生投影将在未来的版本中弃用。

为了演示 GDS 在节点属性上的功能,我们将在 Neo4j 中创建一个小型社交网络图,并将其投影到我们的图目录中。

以下 Cypher 语句将在 Neo4j 数据库中创建示例图:
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'})

写入节点属性

要为社交图中的所有节点标签写入“score”属性,我们使用以下查询

score 属性写回 Neo4j
CALL gds.graph.nodeProperties.write('socialGraph', ['score'])
YIELD propertiesWritten
表 7. 结果
propertiesWritten

4

上面的示例要求 score 属性至少存在于 一个 投影的节点标签上,属性将为所有此类标签写入。

写回时重命名属性

可以重命名节点属性并使用自定义名称将其写回数据库。为此,您可以使用一个映射,其中每个条目都是一个元组 {nodeProperty: 'renamedProperty'},即键对应于内存图中现有的节点属性,值对应于要写回数据库的名称。

为方便起见,一个映射可以包含多个条目。nodeProperties 配置参数接受字符串和映射,以及列表中两者的任意组合。当我们要重命名少量属性时,这会很有帮助。

agescore 属性写回 Neo4j,并为 score 使用新名称
CALL gds.graph.nodeProperties.write('socialGraph', ['age', {score: 'writtenScore'}])
YIELD nodeProperties
表 8. 结果
nodeProperties

["age", "writtenScore"]

在上面的示例中,我们将 age 以其默认名称写回数据库,而通过使用映射将 score 重命名为 writtenScore

NodeLabels(节点标签)

可以将该过程配置为仅写入某些特定节点标签的属性。在以下示例中,我们将仅写回 Person 节点的得分。

将特定投影节点标签的节点属性写入 Neo4j
CALL gds.graph.nodeProperties.write('socialGraph', ['score'], ['Person'])
YIELD propertiesWritten
表 9. 结果
propertiesWritten

3

如果指定了 nodeLabels 参数,则要求 所有 给定的节点标签都具有 所有 给定的属性。

写入节点标签

要为得分高于 0 的节点向数据库写入一个新的节点标签,我们使用以下查询

Reader 节点标签写回 Neo4j
CALL gds.graph.nodeLabel.write('socialGraph', 'Reader', { nodeFilter: 'n.score > 0.0' })
YIELD graphName, nodeCount, nodeLabel, nodeLabelsWritten
表 10. 结果
graphName nodeCount nodeLabel nodeLabelsWritten

"socialGraph"

4

"Reader"

2

查询 Reader 节点标签
MATCH (n:Reader) RETURN n.name AS name, labels(n) AS labels
ORDER BY name ASC
表 11. 结果
名称 (name) 标签

"Adam"

["Person", "Reader"]

"Florentin"

["Person", "Reader"]

从数据库中可以看到,score: 0.0Veselin 不是 Reader