运行作业
Neo4j 图分析提供了一个算法目录,可以通过运行作业来执行。
作业的执行通常分为三个步骤:投影、计算和写入。投影-计算-写入模式是图处理中常见的模式,您首先从数据中投影一个图,然后对该图运行计算,最后将结果写回数据存储。
运行作业时,用户会提交一个类似 JSON 的配置,其中包含与作业步骤对应的键
{
'project': ...,
'compute': ...,
'write': ...
}
我们将描述每个步骤的工作原理和上述配置的相应部分。此结构实际上是 Snowflake SQL 中 VARIANT
类型的数据。它的行为与 JSON 类似,但值得注意的是字符串用单引号表示。
除了 'project'、'compute' 和 'write' 之外,还有一个可选的 defaultTablePrefix
参数,可以简化您提供的输入配置。有关详细信息,请参见下面的默认表前缀部分。
投影
图投影是从 Snowflake 数据库中的表/视图创建图的过程。投影读取两种类型的表(节点表和关系表),以创建针对运行大规模图算法而优化的内存图。输入表必须遵循以下描述的特定约定。
节点表
节点表表示图中的节点。表的每一行代表图中的一个节点。该表必须有一个名为 NODEID
的列,该列唯一标识表中的节点。这些节点标识符支持的数据类型是 BIGINT
和 VARCHAR
。任何其他列都将被视为分配给节点的属性,即所谓的节点属性。
考虑以下节点表示例
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.NODE_DATA (NODEID BIGINT, PROPERTY1 BIGINT, PROPERTY2 DOUBLE);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.NODE_DATA VALUES (1, 42, 13.37), (2, 43, 13.38), (3, 44, 13.39);
在该示例中,我们有两个节点属性:PROPERTY1
和 PROPERTY2
。节点属性支持的数据类型是 NUMBER
、DOUBLE
、FLOAT
和 ARRAY
。
关系表
关系表必须有两个列 SOURCENODEID
和 TARGETNODEID
,用于存储投影中节点表中节点标识符的引用。表的每一行代表图中的一个关系,即从源节点到目标节点的连接。因此,SOURCENODEID
和 TARGETNODEID
列告诉我们图中连接了哪些节点。
关系表还可以有一个附加列,该列被视为关系的属性。这在运行加权图算法时非常有用。
考虑以下关系表示例
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.RELATIONSHIP_DATA (SOURCENODEID BIGINT, TARGETNODEID BIGINT, PROPERTY1 DOUBLE);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.RELATIONSHIP_DATA VALUES (1, 2, 1.0), (2, 3, 2.5);
被投影的图包含三个节点,其中“第一个”与“第二个”以权重 1.0 连接,“第二个”与“第三个”以权重 2.5 连接。SOURCENODEID
和 TARGETNODEID
列引用上述节点表中的 NODEID
列。这也意味着它们必须与 NODEID
列具有相同的数据类型。请注意,如果 SOURCENODEID
和 TARGETNODEID
列引用不同的节点表,它们可以具有不同的类型。任何附加列都被视为关系属性。在该示例中,我们有一个属性 PROPERTY1
。关系属性必须是 DOUBLE
类型。
表的读访问权限
任何作业的投影部分都要求应用程序拥有由管理员授予的读访问权限。
投影配置语法
作业配置的 project
部分的语法是
'project': {
'defaultTablePrefix': OPTIONAL STRING,
'nodeTables': LIST OF STRING,
'relationshipTables': MAP FROM STRING TO MAP
}
其中 nodeTables
的每个元素是节点表的简单名称或完全限定名称,relationshipTables
的每个键是关系表的简单名称或完全限定名称。relationshipTables
中每个条目的值都是一个形式为
{
'sourceTable': STRING,
'targetTable': STRING,
'orientation': OPTIONAL STRING
}
其中 sourceTable
和 targetTable
是节点表中出现的表的简单名称或完全限定名称。在将 sourceTable
和 targetTable
与 nodeTables
的条目进行匹配时,强制执行大小写敏感性。如果 nodeTables
、relationshipTables
、sourceTable
和 targetTable
中的所有或多个表或视图存在于同一架构中,则 defaultTablePrefix
参数可以帮助减少代码量。有关方向,请参阅下面的解释。
从表到异构图的映射
project
配置可能包含多个节点表和关系表。实际上,投影图是一个节点标记和关系类型的图。此类图称为异构图,某些算法可以利用节点标签和关系类型携带的信息。节点标签和关系类型也可以在调用算法时用于过滤图。这样我们就可以在图的子集上运行算法。
源自其中一个节点表的节点都用一个节点标签“标记”,其名称是该节点表的简单名称。例如,db.schema.Person
将生成节点标签 Person
,它区分大小写,尽管 Snowflake 中的表名不区分大小写。
源自其中一个关系表的关系都用一个关系类型“标记”,其名称是该关系表的简单名称。
请注意,由于将简单表名映射到节点标签或关系类型,因此不能使用多个具有相同简单名称的节点表,也不能有两个关系表具有相同的简单名称。节点标签和关系类型都区分大小写,因此例如,投影 person
和 PERSON
标签都是可以的。
我们之前提到,每个节点表在其 NODEID
列中必须具有唯一值。当使用多个节点表时,节点标识符不必在表之间唯一。
方向
在投影配置语法中,我们提到每个关系表都可以使用方向进行投影。方向可以具有 NATURAL
、UNDIRECTED
和 REVERSE
中的一个值。未指定方向时,使用默认的 NATURAL
。NATURAL
方向表示按照表中描述的方向包含关系,即从源节点到目标节点。REVERSE
方向则在包含之前反转表中每个关系的方向,即从目标到源。最后,UNDIRECTED
方向是前两种方向的并集,即每个关系都以原始方向和反向包含。
计算
计算步骤是作业的核心,包括运行一个支持的算法。配置中相应的 compute
部分是算法特定的。然而,某些配置选项(例如 mutateProperty
)由多个算法共享。大多数算法产生的结果通过修改内存中的图来存储,无论是生成节点属性还是在节点之间创建关系。少数算法则生成并存储可在后续作业中用于预测的机器学习模型。
写入
对于生成图输出数据(即节点属性或新关系)的算法,必须配置第三个也是最后一个 write
步骤。每个算法的页面都指定了输出类型,例如,关于写入配置的表格包含 nodeLabel
(如果生成节点属性)和 sourceLabel
、targetLabel
(如果生成关系)。我们首先描述生成节点属性的算法情况。
节点属性
某些算法将其结果输出为节点属性。要将这些节点属性写回 Snowflake,您需要指定一个配置映射列表。每个映射包含一个节点标签和一个输出表的名称。
通用语法是
'write': LIST OF MAP
,其中每个映射的形式为
{'nodeLabel': STRING, 'outputTable': STRING}
并且每个映射都要求将一个节点标签的所有节点写入输出表。outputTable
值在条目之间必须是唯一的。对于每个条目,节点标签必须与表到图映射中的一个节点标签匹配(区分大小写)。写入的输出表包含一个 NODEID
列和一个附加列,该附加列包含要写入的节点属性。
以下示例说明了如何将例如 WCC 的写入结果写回新表
'write': [
{'nodeLabel': 'CUSTOMERS', 'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.CUSTOMERS_COMPONENTS'}
]
由于应用程序将写入一个表(在本例中为 EXAMPLE_DB.DATA_SCHEMA.CUSTOMERS_COMPONENTS ),因此在运行作业之前,必须授予应用程序写入权限。 |
如果输出表已存在,应用程序将在具有相应权限的情况下覆盖该表。
关系属性
现在我们将讨论由算法创建的关系的写入。输出关系属性的算法会在投影的内存图中创建关系。这些关系可以根据每个关系的源节点和目标节点的节点标签进行分组。由于目前没有算法生成不同类型的关系,因此输出关系上不公开关系类型。
写入配置遵循以下语法
'write': LIST OF MAP
,其中每个映射的形式为
{'sourceLabel': STRING, 'targetLabel': STRING, 'outputTable': STRING}
sourceLabel
和 targetLabel
值根据源和目标节点标签的分组确定要写入的关系子集。输出表包含 SOURCENODEID
和 TARGETNODEID
列。如果算法在关系上生成属性,它还包含一个附加列,该列保存要写入的关系属性。
以下示例演示了如何将例如节点相似度算法计算的关系写回,包括其计算的属性(SCORE
)
'write': [
{'sourceLabel': 'ORDERS', 'targetLabel': 'ORDERS', 'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.ORDER_SIMILARITIES'}
]
由于应用程序将写入一个表(在本例中为 EXAMPLE_DB.DATA_SCHEMA.ORDER_SIMILARITIES ),因此在运行作业之前,必须授予应用程序写入权限。 |
如果输出表已存在,应用程序将在具有相应权限的情况下覆盖该表。
运行作业示例
让我们考虑一个包含多个节点表和关系表的更复杂的示例。
下表代表了事务性商店系统的一个子集。通常,实际场景中的表会包含更多的列和行。这里,我们创建一个 VIEW
来将源表转换为可用于图投影的格式。
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.PRODUCTS (nodeId Number, price Double);
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.ORDERS (nodeId Number, total Number);
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.CUSTOMERS (nodeId Number);
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.LINEITEM (sourceNodeId Number, targetNodeId Number, quantity Double);
CREATE TABLE EXAMPLE_DB.DATA_SCHEMA.PURCHASE (sourceNodeId Number, targetNodeId Number);
为了从这些表创建图,我们需要定义节点表和关系表及其映射。一个示例是节点相似度算法,该算法可用于根据 LINEITEM
和 PURCHASE
关系查找相似产品。该算法将生成新的关系,连接具有各种标签的相似节点。这些关系将包含一个 similarity
属性,其中包含连接节点之间相似度的分数。最后,我们将产品到产品和订单到订单的相似关系写回 Snowflake 表以进行进一步分析。
另请注意,在以下示例中,我们使用默认应用程序名称 Neo4j_Graph_Analytics
。如果您在安装过程中选择了不同的应用程序名称,请将其替换。
CALL Neo4j_Graph_Analytics.graph.node_similarity('CPU_X64_XS', {
'defaultTablePrefix': 'EXAMPLE_DB.DATA_SCHEMA',
'project': {
'nodeTables': ['PRODUCTS', 'ORDERS', 'CUSTOMERS'],
'relationshipTables': {
'LINEITEM': {
'sourceTable': 'ORDERS',
'targetTable': 'PRODUCTS'
},
'PURCHASE': {
'sourceTable': 'CUSTOMERS',
'targetTable': 'PRODUCTS'
}
}
},
'compute': {'topK': 2},
'write': [
{'sourceLabel': 'CUSTOMERS', 'targetLabel': 'CUSTOMERS', 'outputTable': 'CUSTOMER_SIMILARITIES'},
{'sourceLabel': 'ORDERS', 'targetLabel': 'ORDERS', 'outputTable': 'ORDER_SIMILARITIES'}
]
});
请注意,这里的 defaultTablePrefix
用于为配置中的所有表指定默认数据库和架构。有关详细信息,请参见默认表前缀部分。