本系列的前二篇请参见:
8. 以数据流方式返回节点属性
我们可以将存储在命名内存图中的节点属性流式传输回用户。 如果我们在mutate模式下运行多个算法并想要检索部分或全部结果,这将非常有用。 这类似于stream执行模式的作用,但允许对操作进行更细粒度的控制。
CALL gds.graph.streamNodeProperties('my-graph', ['componentId', 'pageRank', 'communityId'])
上面的示例要求所有给定的属性都存在于至少一个节点投影上,并且这些属性将针对所有此类投影进行流式传输。
该过程可以配置为仅流式传输某些特定节点投影的属性。 在下面的示例中,我们在子图上运行了一个算法,然后流式传输新创建的属性。
CALL gds.graph.create('my-graph', ['A', 'B'], '*')
CALL gds.wcc.mutate('my-graph', {nodeLabels: ['A'], mutateProperty: 'componentId'})
CALL gds.graph.streamNodeProperties('my-graph', ['componentId'], ['A'])
当指定不是 * 的投影列表时,如上例所示,将应用不同的验证和执行。 然后要求所有投影都具有所有给定的属性,并且它们将针对所有投影进行流式传输。
如果任何给定的投影是“*”,则该过程的行为与第一个示例中的一样。
流式传输多个节点属性时,每个属性的名称都包含在结果中。 这会增加一些开销,因为必须为结果中的每个节点重复每个属性名称,但这是区分属性所必需的。对于流式传输单个节点属性,这不是必需的。gds.graph.streamNodeProperty()从内存图中流式传输单个节点属性,并省略属性名称。 结果的格式为nodeId
, propertyValue
, 这与许多算法过程的流模式很相似。
CALL gds.graph.streamNodeProperty('my-graph', 'componentId')
9. 流关系属性
我们可以将存储在命名内存图中的关系属性流式传输回用户。 如果我们在mutate模式下运行多个算法并想要检索部分或全部结果,这将非常有用。 这类似于stream执行模式的作用,但允许对操作进行更细粒度的控制。
CALL gds.graph.streamRelationshipProperties('my-graph', ['similarityScore', 'weight'])
该过程可以配置为仅流式传输某些特定关系投影的属性。 在下面的示例中,我们在子图上运行了一个算法,然后流式传输新创建的属性。
CALL gds.graph.create('my-graph', ['*'], [A', 'B'])
CALL gds.nodeSimiliarity.mutate('my-graph', {relationshipTypes: ['A'], mutateRelationshipType: 'R', mutateProperty: 'similarityScore'})
CALL gds.graph.streamNodeProperties('my-graph', ['similarityScore'], ['R'])
当指定不是 * 的投影列表时,如上例所示,将应用不同的验证和执行。 然后要求所有投影都具有所有给定的属性,并且它们将针对所有投影进行流式传输。
如果任何给定的投影是“*”,则该过程的行为与第一个示例中的一样。
流式传输多个关系属性时,结果中包含关系类型和每个属性的名称。 这增加了一些开销,因为必须为结果中的每个关系重复每个类型名称和属性名称,但这是区分属性所必需的。 gds.graph.streamNodeProperty()对于流式处理单个关系属性,可以省略属性名称。从内存图中流式传输单个关系属性,并省略属性名称。结果的格式为sourceNodeId
, targetNodeId
, relationshipType
, propertyValue
。
CALL gds.graph.streamRelationshipProperty('my-graph', 'similarityScore')
10. 将节点属性写入 Neo4j
类似于存储在内存图中的流属性,也可以将它们写回 Neo4j。
这也类似于write执行模式的作用,但允许对操作进行更细粒度的控制。
要写入的属性通常是运行算法时使用的mutateProperty值。 在创建时添加到创建的图形中的属性通常已经存在于 Neo4j 数据库中。
10.1. 句法
CALL gds.graph.writeNodeProperties(
graphName: String,
nodeProperties: List<String>,
nodeLabels: List<String>,
configuration: Map
) YIELD
graphName: String,
nodeProperties: List<String>,
writeMillis: Integer,
propertiesWritten: Integer
表 9. 参数
Name | Type | Default | Optional | Description |
---|---|---|---|---|
graphName | String |
| no | The name of a graph stored in the catalog. |
nodeProperties | List<String> |
| no | Names of properties to write. |
nodeLabels | List<String> |
| yes | Names of labels to write properties for. |
configuration | Map |
| yes | Configuration for algorithm-specifics and/or graph filtering. |
表 10. 配置参数
Name | Type | Default | Optional | Description |
---|---|---|---|---|
concurrency | Integer |
| yes | The number of concurrent threads used for writing the properties to Neo4j. |
writeConcurrency | Integer |
| yes | The number of concurrent threads used for writing the properties to Neo4j. If both |
表 11. 结果
Name | Type | Description |
---|---|---|
| String | Name of the graph. |
| List<String> | Names of written properties. |
| Integer | Milliseconds for writing properties to Neo4j. |
| Integer | Number of properties written. |
10.2. 例子
要使用 8 个并发线程为'my-graph'图中的所有节点投影编写属性'componentId'
, 'pageRank'
, 'communityId'
,请使用以下查询:
CALL gds.graph.writeNodeProperties(
'my-graph',
['componentId', 'pageRank', 'communityId'],
['*'],
{writeConcurrency: 8}
)
上面的示例要求所有给定的属性都存在于至少一个节点投影上,并且将为所有此类投影编写属性。
该过程可以配置为仅写入某些特定节点投影的属性。 在以下示例中,我们在子图上运行算法,然后将新创建的属性写入 Neo4j。
CALL gds.graph.create('my-graph', ['A', 'B'], '*')
CALL gds.wcc.mutate('my-graph', {nodeLabels: ['A'], mutateProperty: 'componentId'})
CALL gds.graph.writeNodeProperties('my-graph', ['componentId'], ['A'])
当指定了不包括星形投影 ('*') 的投影列表时,如上例所示,将应用不同的验证和执行。 在这种情况下,要求所有投影都具有所有给定的属性,并且它们将针对所有投影写入 Neo4j。
如果任何给定的投影是星形投影,则该过程的行为与第一个示例中的一样。
11. 写关系到 Neo4j
我们可以将存储在命名内存图中的关系写回 Neo4j。 这可用于编写算法结果(例如:来自节点相似性)或在图创建期间聚合的关系。
要写入的关系由关系类型指定。 这可以是图构建期间关系投影中使用的元素标识符,也可以是创建关系的算法中使用的writeRelationshipType。 关系总是使用单个线程编写。
CALL gds.graph.writeRelationship('my-graph', 'SIMILAR_TO')
默认情况下,不会写入任何关系属性。 要编写关系属性,必须明确指定这些属性。
CALL gds.graph.writeRelationship('my-graph', 'SIMILAR_TO', 'similarityScore')
12. 从命名图创建 Neo4j 数据库
我们可以从存储在图目录中的命名内存图创建新的 Neo4j 数据库。 内存图中存在的所有节点、关系和属性都写入新的 Neo4j 数据库。 这包括在gds.graph.create中投影的数据和通过在mutate模式下运行算法添加的数据。 新创建的数据库将使用给指定的数据库名称存储在 Neo4j 数据库目录中。
此特性在以下示例性场景中很有用:
- 通过导出数据而不是回写来避免操作系统上的大量写入负载。
- 创建可用作运行算法基础的操作系统的分析视图。
- 生成分析结果的快照并将其持久化以供存档和检查。
- 在组织内共享分析结果。
CALL gds.graph.export('my-graph', { dbName: 'mydatabase' })
该过程产生关于节点数量、关系和写入的属性的信息。
表 12. 图形导出配置
Name | Type | Default | Optional | Description |
---|---|---|---|---|
dbName | String |
| No | Name of the exported Neo4j database. |
writeConcurrency | Boolean |
| yes | The number of concurrent threads used for writing the database. |
enableDebugLog | Boolean |
| yes | Prints debug information to Neo4j log files. |
batchSize | Integer |
| yes | Number of entities processed by one single thread at a time. |
defaultRelationshipType | String |
| yes | Relationship type used for |
可以使用数据库管理命令启动新数据库。
使用导出程序时数据库不能存在,需要使用以下命令手动创建。
:use system
CREATE DATABASE mydatabase;
:use mydatabase
MATCH (n) RETURN n;
13. 将命名图导出为 CSV beta
我们可以将存储在图形目录中的命名内存图形导出到一组 CSV 文件中, 内存图中存在的所有节点、关系和属性都被导出。 这包括使用gds.graph.create投影的数据和通过在mutate模式下运行算法添加的数据。 导出的 CSV 文件的位置可以通过neo4j.conf中的配置参数gds.export.location进行配置。 所有文件都将使用指定的导出名称存储在子文件夹中。 如果具有给定导出名称的文件夹已存在,则导出将失败。
必须为此功能配置gds.export.location参数。
CALL gds.beta.graph.export.csv('my-graph', {exportName: 'myExport'})
该过程产生关于节点数量、关系和写入的属性的信息。
表 13. 图导出配置
Name | Type | Default | Optional | Description |
---|---|---|---|---|
exportName | String |
| No | Name of the folder to which the CSV files are exported. |
writeConcurrency | Boolean |
| yes | The number of concurrent threads used for writing the database. |
defaultRelationshipType | String |
| yes | Relationship type used for |
13.1. 导出格式
导出的 CSV 文件的格式基于 Neo4j Admin 导入命令支持的格式。
13.1.1. 节点
节点被导出到按节点标签分组的文件中,即,对于图中存在的每个标签组合,都会创建一组导出文件。 导出文件的命名模式为:nodes_LABELS_INDEX.csv,其中:
- LABELS是由 _连接的标签的有序列表。
- INDEX是一个介于 0 和并发之间的数字。
对于每个标签组合,都会创建一个或多个数据文件,因为每个导出器线程都导出到一个单独的文件中。
此外,每个标签组合都会生成一个头文件,其中包含一行描述数据文件中的列。有关头文件的更多信息可以在此处找到:CSV header format。
例如,具有节点组合 :A
, :B
and :A:B
的图可能会创建以下文件。
nodes_A_header.csv
nodes_A_0.csv
nodes_B_header.csv
nodes_B_0.csv
nodes_B_2.csv
nodes_A_B_header.csv
nodes_A_B_0.csv
nodes_A_B_1.csv
nodes_A_B_2.csv
13.1.2. 关系
关系文件的格式与节点的格式类似, 关系导出到按关系类型分组的文件中。 导出文件的命名模式为:relationships_TYPE_INDEX.csv,其中:
- TYPE是关系类型
- INDEX是一个介于 0 和并发之间的数字。
对于每种关系类型,都会创建一个或多个数据文件,因为每个导出器线程都导出到一个单独的文件中。
此外,每种关系类型都会生成一个头文件,其中包含一行描述数据文件中的列。
例如,关系类型为 : :KNOWS
, :LIVES_IN
的图可能会创建以下文件
relationships_KNOWS_header.csv
relationships_KNOWS_0.csv
relationships_LIVES_IN_header.csv
relationships_LIVES_IN_0.csv
relationships_LIVES_IN_2.csv
13.2. 估计
使用gds.graph.export.csv.estimate过程可以估计导出的 CSV 文件所需的磁盘空间。 估计使用采样来生成更准确的估计。
CALL gds.beta.graph.export.csv.export('my-graph', {exportName: 'myExport'})
YIELD nodeCount, relationshipCount, bytesMin, bytesMax, requiredMemory;
该过程会生成有关所需磁盘空间的信息。
Name | Type | Default | Optional | Description |
---|---|---|---|---|
exportName | String |
| No | Name of the folder to which the CSV files are exported. |
samplingFactor | Double |
| yes | The fraction of nodes and relationships to sample for the estimation. |
writeConcurrency | Boolean |
| yes | The number of concurrent threads used for writing the database. |
defaultRelationshipType | String |
| yes | Relationship type used for |