跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

IMPORT

IMPORT语句用于向临时图导入数据。该语句通常与 USE 子句配合使用,后者用于指定目标临时图。数据可以来自文件、悦数图数据库开发版或表变量。

前提条件

注意事项

不同导入方式的主要限制如下:

数据来源和导入方式 图类型或字段映射要求 边类型要求 其他限制
从悦数图数据库开发版导入完整的图 临时图的图类型定义(点/边类型及其属性)必须与源图一致。 无额外要求。 源图和目标临时图不得运行在同一 Graph 服务上。
从悦数图数据库开发版导入指定类型的点/边 源点类型的主键结构、源边类型的拓扑结构必须与目标定义对应。 临时图的边类型必须声明MULTIEDGE KEY()。 源图和目标临时图不得运行在同一 Graph 服务上。
从文件导入 文件字段必须与目标属性正确映射;未映射的属性必须有默认值或允许为NULL。 临时图的边类型必须声明MULTIEDGE KEY()。 文件格式和字段类型必须受支持。
从表变量导入 表字段类型必须与目标属性类型兼容;未映射的属性必须有默认值或允许为NULL。 临时图的边类型必须声明MULTIEDGE KEY()。 表变量必须在IMPORT前定义。

例如,需要声明多重边键时,可将边类型定义为EDGE Friend (Person)-[:Friend {since DATE, MULTIEDGE KEY()}]->(Person)。

语法

import_statement
IMPORT INTO GRAPH { node_definition file_source graph_source table_source edge_definition file_source graph_source table_source , GRAPH graph_source } OPTIONS { data_option , }
node_definition
NODE ( node_variable @ node_type_name { property_name : field_name , } )
edge_definition
EDGE ( primary_key_property_name : field_name , ) -[ edge_variable @ edge_type_name { property_name : field_name , } ]-> <-[ edge_variable @ edge_type_name { property_name : field_name , } ]- ~[ edge_variable @ edge_type_name { property_name : field_name , } ]~ ( primary_key_property_name : field_name , )
file_source
FROM file_variable DATAFILE { file_options }
file_options
PATH : file_path , FORMAT : " CSV " " PARQUET " " ORC " , additional_options
file_path
" file:// path " " hdfs:// hostname : port / path " " s3:// access_key : secret_key @ bucket / path ? parameter_name = parameter_value & " " gs:// access_key : secret_key anonymous @ bucket / path ? parameter_name = parameter_value & "
graph_source
FROM NEBULA { PATH : " nebula_uri_string " , FORMAT : " NEBULA " }
nebula_uri_string
nebula:// username : password @ graph_address ? graph = graph_name & schema = schema_path & node_type = source_node_type_name & edge_type = source_edge_type_name & tls_parameter_name = tls_parameter_value
table_source
FROM table_variable
data_option
PRIMARY_KEY_AS_NODE_ID : true false SKIP_CONFLICT_PK_NODES : true false SKIP_DANGLING_EDGES : true false

import_statement ::=
    'IMPORT' 'INTO' 'GRAPH' '{' ( ( (node_definition (file_source | graph_source | table_source) | edge_definition (file_source | graph_source | table_source)) (',' (node_definition (file_source | graph_source | table_source) | edge_definition (file_source | graph_source | table_source) ))* )| 'GRAPH' graph_source ) '}' ( 'OPTIONS' '{' data_option ( ',' data_option )* '}' )? 

node_definition ::=
    'NODE' '(' node_variable '@' node_type_name '{' (property_name ':' field_name) (',' (property_name ':' field_name))* '}' ')'

edge_definition ::=
    'EDGE' '(' (primary_key_property_name ':' field_name) (',' (primary_key_property_name ':' field_name) )* ')' ( ( '-[' edge_variable '@' edge_type_name '{' ((property_name ':' field_name) (',' (property_name ':' field_name))*)? '}' ']->' ) 
    |  ('<-[' edge_variable '@' edge_type_name '{' ((property_name ':' field_name) (',' (property_name ':' field_name))*)? '}' ']-' )  
    |  ('~[' edge_variable '@' edge_type_name '{' ((property_name ':' field_name) (',' (property_name ':' field_name))*)? '}' ']~' ) )
    '(' (primary_key_property_name ':' field_name) (','(primary_key_property_name ':' field_name) )* ')' 

file_source ::=
    'FROM' ( file_variable | ( 'DATAFILE' '{' file_options  '}' ) )

file_options ::=
    ('PATH' ':' file_path) ',' ('FORMAT' ':' ('"' 'CSV' '"'|'"' 'PARQUET' '"'|'"' 'ORC' '"')(',' additional_options)* )

file_path ::=
    '"' 'file://' path '"' 
    | '"' 'hdfs://' hostname ':' port '/' path '"' 
    | '"' 's3://' (access_key ':' secret_key '@')? bucket '/' path ( '?' ( parameter_name '=' parameter_value) ('&' ( parameter_name '=' parameter_value))* )? '"'
    | '"' 'gs://' ((access_key ':' secret_key) | 'anonymous') '@' bucket '/' path ( '?' ( parameter_name '=' parameter_value) ('&' ( parameter_name '=' parameter_value))* )? '"' 

graph_source ::=
    'FROM' 'NEBULA' '{' 'PATH' ':' '"' nebula_uri_string '"' ',' 'FORMAT' ':' ('"' 'NEBULA' '"') '}'          

nebula_uri_string ::= 
    'nebula://' username ':' password '@' graph_address '?' ( 'graph' '=' graph_name) ('&' 'schema' '=' schema_path)? (('&' 'node_type' '=' source_node_type_name) | ('&' 'edge_type' '=' source_edge_type_name))? ('&' ( tls_parameter_name '=' tls_parameter_value))*

table_source ::=
    'FROM' table_variable

data_option ::= 
    'PRIMARY_KEY_AS_NODE_ID' ':' ( 'true' | 'false' ) 
    | 'SKIP_CONFLICT_PK_NODES' ':' ( 'true' | 'false' ) 
    | 'SKIP_DANGLING_EDGES' ':' ( 'true' | 'false' )     

参数

node_variable

指代临时图中的点的变量。更多信息,请参见变量表达式。

node_type_name

创建临时图所引用的图类型中定义的点类型名称。

property_name

点类型或边类型对应的属性名称。

field_name

file_source指定的文件中的字段名称或者graph_source指定的图中的属性名称。该参数的值用于填充临时图中对应的属性。

若没有给某个属性指定对应的字段,则使用图类型中定义的该属性的默认值。若该属性声明为NOT NULL、没有默认值且未映射字段,则导入会报错。

primary_key_property_name

与边连接的点中作为主键的属性名称。如果主键由多个属性组成,则必须列出所有主键属性。

edge_variable

指代临时图中的边的变量。更多信息,请参见变量表达式。

edge_type_name

创建临时图所引用的图类型中定义的边类型名称。

file_source

从中读取数据以填充临时图的文件数据源。

注意,在同一条IMPORT语句中,不支持同时指定file_source和graph_source。

file_variable

从中读取数据以填充临时图的文件变量。该变量必须在使用 IMPORT 语句之前定义。更多信息,请参见文件变量。

在 CSV 文件导入场景下,如果文件变量中为列声明的类型(value_type)与该列的实际数据值兼容,系统会按声明的类型解析该列的 CSV 文本。当前自动识别并解析的类型包括:所有整数、浮点数、字符串、布尔。关于数据类型,请参见数据类型。

file_options

文件配置项,包括PATH、FORMAT以及特定格式的配置项。PATH和FORMAT必填;其他所有配置项可选。配置项可以以任意顺序出现。

支持的文件格式包括:CSV、PARQUET和ORC。

有关可选配置项,请参见下方的参数additional_options。

file_path

从中读取数据的文件路径。支持存储位置包括本地文件系统、Hadoop 分布式文件系统(HDFS)以及云存储服务(如 Amazon S3 和 Google Cloud Storage)。该参数在 file_source 中为必填项。

path

存储服务中数据文件的绝对路径。

若该路径指向单个文件,则只读取该文件;若该路径指向一个目录,则读取该目录下的所有文件,且这些文件都须对应相同的点类型或边类型。

Note

若指定本地路径,请确保系统具有该路径的访问权限。

hostname和port

用于访问存储服务的主机名或 IP 地址及端口。

access_key和secret_key

用于访问云存储服务的 Access Key 和 Secret Key。

在访问 Amazon S3 时,也支持将 Access Key 和 Secret Key 指定为文件路径中的参数(parameter_name)。

在访问 GCS 时,也支持省略 Access Key 和 Secret Key,而是指定anonymous来访问公共存储桶。

bucket

云存储服务中数据读取的存储桶名称。

parameter_name和parameter_value

从云存储服务读取文件时的参数。

在访问 Amazon S3 时,支持指定以下参数:

  • access_key:用于访问 S3 存储桶的 Access Key。
  • secret_key:用于访问 S3 存储桶的 Secret Key。
  • region:S3 存储桶所在的区域。
  • scheme:访问 S3 存储桶的协议,例如http或https。
  • endpoint_override:用于覆盖默认 S3 端点的自定义端点。

在访问 GCS 时,支持指定以下参数:

  • scheme:访问 GCS 存储桶的协议,例如http或https。
  • endpoint_override:用于覆盖默认 GCS 端点的自定义端点。
  • retry_limit_seconds:读取文件失败时,重试的最大时间(以秒为单位)。若超过此时间仍未成功,则返回错误。

additional_options

用于配置文件读取、解析和转换的额外配置项。这些配置项根据文件格式的不同而有所差异。支持的配置项包括:

文件类型 类别 配置项名称 数据类型 说明
CSV 读取 USE_THREADS Bool 是否使用全局 CPU 线程池进行读取。
读取 BLOCK_SIZE Int32 I/O 操作的块大小;影响多线程粒度和记录批次大小。
读取 SKIP_ROWS Int32 读取列前跳过的表头行数。
读取 SKIP_ROWS_AFTER_NAMES Int32 读取列后跳过的行数。
读取 COLUMN_NAMES Vector 表的显式列。
读取 AUTOGENERATE_COLUMN_NAMES Bool 当未提供列名时,是否自动生成列名(例如f0、f1)。
解析 DELIMITER Char 列的分隔符字符。
解析 QUOTING Bool 是否启用引号。
解析 QUOTE_CHAR Char 值的引用字符。
解析 DOUBLE_QUOTE Bool 值内部的引号是否由双引号表示。
解析 ESCAPING Bool 是否启用转义。
解析 ESCAPE_CHAR Char 特殊字符的转义字符。
解析 NEWLINES_IN_VALUES Bool 值中是否可能包含换行符。
解析 IGNORE_EMPTY_LINES Bool 是否忽略空行。
转换 CHECK_UTF8 Bool 是否验证字符串列的 UTF-8 编码。
转换 NULL_VALUES Vector 被解释为 null 值的字符串。
转换 TRUE_VALUES Vector 被解释为布尔值true的字符串。
转换 FALSE_VALUES Vector 被解释为布尔值false的字符串。
转换 STRINGS_CAN_BE_NULL Bool 字符串/二进制列是否可能包含 null 值。
转换 QUOTED_STRINGS_CAN_BE_NULL Bool 引用的字符串值是否可被视为 null。
转换 INCLUDE_COLUMNS Vector 输出中包含的列;未列出的列将被忽略。
转换 INCLUDE_MISSING_COLUMNS Bool 是否为INCLUDE_COLUMNS中列出但缺失的列创建 null 值。
Parquet 读取 BUFFER_SIZE Int64 缓冲流的大小(以字节为单位)。
读取 BUFFERED_STREAM Bool 是否启用缓冲流读取以控制内存使用。
读取 THRIFT_STRING_SIZE_LIMIT Int32 Thrift 字符串大小限制,防止因大型头部导致内存过度使用。
读取 THRIFT_CONTAINER_SIZE_LIMIT Int32 Thrift 容器大小限制,防止因大型头部导致内存过度使用。
读取 BUFFERED_STREAM_ENABLED Bool 是否启用缓冲流读取。
读取 PAGE_CHECKSUM_VERIFICATION Bool 读取时是否验证页校验和。
读取 READ_DENSE_FOR_NULLABLE Bool 是否优化可空列的读取。
读取 USE_THREADS Bool 是否使用多个线程并行解析列。
读取 BATCH_SIZE Int64 读取时每个记录批次的最大行数。
读取 PRE_BUFFER Bool 是否通过预缓冲文件区域来合并读取(有助于高延迟文件系统)。
ORC 不支持读取配置。 - - -

graph_source

从中读取数据以填充临时图的持久图数据源。

注意:

  • 在同一条IMPORT语句中,不支持同时指定file_source和graph_source。
  • 在同一条IMPORT语句中,只能从同一个图数据源导入数据。也即每个graph_source中指定的nebula_uri_string必须完全一致。

FORMAT和PATH

graph_source中必需设置的关键字,分别用于定义图数据的格式和路径,填写顺序任意。

支持的格式为NEBULA,也即悦数图数据库开发版作为数据源。

nebula_uri_string

用于连接悦数图数据库开发版的 URI 字符串。此参数在graph_source中必填。

username

连接悦数图数据库开发版的用户名。

password

连接悦数图数据库开发版的密码。

graph_address

连接悦数图数据库开发版中 Graph 服务的地址。格式为ip:port。

graph_name

从悦数图数据库开发版读取的图的名称。此图必须已经存在于悦数图数据库开发版中。

该图的图类型必须与graph_type_name指定的图类型一致。

schema_path

从悦数图数据库开发版读取的图所属的 Schema 路径。该路径必须为绝对路径。

当未指定&schema=schema_path时,默认使用主 Schema。

source_node_type_name

悦数图数据库开发版中点类型的名称。当通过node_definition读取指定点时,该参数必填。

此处指定的点类型的主键结构,必须与node_definition中定义的点类型的主键结构一致,即列的数量和顺序必须相同。例如,node_definition中定义点类型Actor的主键为PRIMARY KEY (id, name),则此处点类型的主键也必须由两列组成,如PRIMARY KEY (id_, name_),列名可以不同(如id对应id_),但列的数量和顺序必须匹配,以确保主键能正确映射。

source_edge_type_name

悦数图数据库开发版中边类型的名称。当通过edge_definition读取指定边时,该参数必填。

此处指定的边类型的拓扑结构必须与edge_definition中定义的边类型的拓扑结构一致,即边的起点和终点的点类型必须分别一致。例如,edge_definition中定义的边类型为(Actor)-[:Act {MULTIEDGE KEY()}]->(Movie),此处指定的边类型为(Actor_)-[:Act_ {MULTIEDGE KEY()}]->(Movie_),则必须保证连接的点类型定义分别一一对应,即Actor和Movie的点类型定义必须分别与Actor_和Movie_映射。

tls_parameter_name

连接悦数图数据库开发版时,可配置的其他参数的名称。支持配置以下 TLS 相关参数:

参数名称 数据类型 是否必需 描述 有效值/示例
tls_enable Boolean 是 是否开启 TLS。当悦数图数据库开发版的 Graph 服务启用了 TLS 时, 此参数必须设置为true。 true、false、1和0
tls_cert String 是 客户端证书文件的路径。仅当 Graph 服务的配置文件里将tls_client_verify设置为true时配置。 /path/to/client-cert.pem
tls_key String 是 客户端私钥文件的路径。仅当 Graph 服务的配置文件里将tls_client_verify设置为true时配置。 /path/to/client-key.pem
tls_ca String 是 CA 证书文件的路径。 /path/to/ca-cert.pem
tls_cadir String 否 CA 证书目录的路径。当tls_ca未配置时,此参数生效。 /path/to/ca-certs/
tls_peer_name String 否 服务端证书中的 CN 或 SAN 字段。若未指定,则使用主机名或 IP 地址进行验证。 server.example.com
tls_peer_name_verify Boolean 否 是否验证服务端证书中的 CN 或 SAN 字段。 true和false
tls_passfile String 否 加密私钥文件的路径。 /path/to/passfile
tls_ciphers String 否 TLS 1.2 密码套件。仅当tls_versions设置为TLSv1.2时配置。 ECDHE-RSA-AES256-GCM-SHA384
tls_ciphersuites String 否 TLS 1.3 密码套件。仅当tls_versions设置为TLSv1.3时配置。 TLS_AES_256_GCM_SHA384
tls_versions String 否 指定允许使用的 TLS 协议版本,以逗号分隔。 TLSv1.2, TLSv1.3
tls_parameter_value

指定的tls_parameter_name对应的参数值。值的示例请参见上表。

table_source

从中读取数据以填充临时图的表数据源。表是查询执行过程中创建的内存表变量。

注意,在同一条IMPORT语句中,不支持同时指定table_source和graph_source。

从表变量导入时,系统会进行严格的类型检查:表中列的数据类型必须与图类型中对应的属性类型一致。与文件导入不同,不支持隐式类型转换(例如 STRING 到 INT)。若类型不兼容,导入会因类型不匹配而失败。

表变量中可以包含未映射到点或边定义属性的多余列,这些列在导入时会被忽略。

若图类型中定义的属性未映射到表变量列,则使用图类型中定义的默认值。若该属性没有默认值且被标记为NOT NULL,则导入会失败并报错。

table_variable

过程体内定义的表变量名称。表变量必须在IMPORT语句引用之前定义。更多信息,请参见表变量。

data_option

导入数据至临时图时的数据处理选项。支持的选项如下:

选项 类型 默认值 描述
PRIMARY_KEY_AS_NODE_ID Bool - 指定是否使用充当主键的属性值作为点的唯一标识符。该选项仅在以下条件全部满足时生效:
  • 临时图是基于图类型创建的。
  • 主键仅由一个属性组成,且该属性类型为不超过 4 个字节的整数。
  • 导入该临时图的数据来自悦数图数据库开发版之外的源。
当满足上述生效条件时,系统将自动使用主键属性值作为点的唯一标识符;不满足时(例如主键由多个属性组成),该选项将自动禁用。支持显式指定true或false覆盖系统行为。显式设置仅适用于整数类型主键;当设置为true时,主键值必须在 6 字节可表示范围内,否则导入失败。
SKIP_CONFLICT_PK_NODES Bool false 指定是否跳过主键重复的点。该选项仅在以下条件全部满足时生效:
  • 临时图是基于图类型创建的。
  • 导入该临时图的数据来自悦数图数据库开发版之外的源。
当导入的数据中存在主键重复的点时,必须将SKIP_CONFLICT_PK_NODES设为true,否则会导致导入失败。
SKIP_DANGLING_EDGES Bool false 指定是否跳过悬挂边。该选项仅在临时图是基于图类型创建时生效。
当导入的数据中存在悬挂边时,必须将SKIP_DANGLING_EDGES设为true,否则会导致导入失败。

示例

从悦数图数据库开发版导入数据

从悦数图数据库开发版导入完整的图

'''
// 创建名为`movie_type`的图类型
CREATE GRAPH TYPE IF NOT EXISTS movie_type AS { 
    NODE Actor (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}) , 
    NODE Director (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}), 
    NODE `User` (LABEL Person {id INT64 PRIMARY KEY}), 
    NODE Movie (LABEL Movie {id INT64 PRIMARY KEY, name STRING}), 
    NODE Genre (LABEL Genre {id INT64 PRIMARY KEY, name STRING}), 
    EDGE Act (Actor)-[:Act]->(Movie), 
    EDGE Direct (Director)-[:Direct]->(Movie), 
    EDGE Watch (`User`)-[:Watch {rate FLOAT}]->(Movie), 
    EDGE WithGenre (Movie)-[:WithGenre]->(Genre) 
    }
'''

'''
// 基于图类型`movie_type`创建名为`#movie_temporary_graph`的临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #movie_temporary_graph TYPED movie_type
'''

'''
USE #movie_temporary_graph IMPORT INTO GRAPH { 
  GRAPH FROM NEBULA { 
  FORMAT: "NEBULA", 
  // 替换为实际的悦数图数据库开发版连接信息
  PATH: "nebula://root:<password>@<graph_host>:<graph_port>?graph=movie&schema=/default_schema" 
  }  
}
'''

'''
// 验证临时图的统计数据
USE #movie_temporary_graph SHOW STATS
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 4589      |
| Edge Total | Edge         | 10175     |
+------------+--------------+-----------+

从悦数图数据库开发版导入指定类型的点和边

'''
// 创建含带有 MULTIEDGE KEY() 约束的边类型的图类型`movie_type`                                               
CREATE GRAPH TYPE IF NOT EXISTS movie_type AS {                                                   
    NODE Actor (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}) ,         
    NODE Director (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}),       
    NODE `User` (LABEL Person {id INT64 PRIMARY KEY}),                                            
    NODE Movie (LABEL Movie {id INT64 PRIMARY KEY, name STRING}),                                 
    NODE Genre (LABEL Genre {id INT64 PRIMARY KEY, name STRING}),                                 
    EDGE Act (Actor)-[:Act {MULTIEDGE KEY()}]->(Movie)                                                                   
    }                                                                                             
'''

'''
// 基于图类型`movie_type`创建名为`#movie_import`的临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #movie_import TYPED movie_type
'''

'''
USE #movie_import IMPORT INTO GRAPH 
{
  NODE (v@Actor{id:id, name:name}) FROM NEBULA { 
    FORMAT: "NEBULA", 
    PATH: "nebula://root:<password>@<graph_host>:<graph_port>?graph=movie&node_type=Actor"
  },
  NODE (v@Movie{id:id, name:name}) FROM NEBULA { 
    FORMAT: "NEBULA", 
    PATH: "nebula://root:<password>@<graph_host>:<graph_port>?graph=movie&node_type=Movie"
  },
  EDGE (id:id)-[e@Act{}]->(id:id) FROM NEBULA { 
    FORMAT: "NEBULA", 
    PATH: "nebula://root:<password>@<graph_host>:<graph_port>?graph=movie&edge_type=Act"
  }
}
'''

'''
// 验证临时图的统计数据
USE #movie_import SHOW STATS
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 3557      |
| Edge Total | Edge         | 3732      |
+------------+--------------+-----------+

从文件/文件变量导入数据

从 CSV 文件导入

以下示例使用文件pagerank_node.csv和pagerank_edge.csv作为源数据。

pagerank_node.csv
u_id,u_name
1,Alice
2,Bob
3,Charlie
4,David
pagerank_edge.csv
src_id,dst_id,src_name,dst_name
1,2,Alice,Bob
2,3,Bob,Charlie
1,4,Alice,David
3,4,Charlie,David
4,2,David,Bob
'''
// 创建名为`pagerank_graph_type`的图类型
CREATE GRAPH TYPE IF NOT EXISTS pagerank_graph_type AS { 
    NODE Person (LABEL Person {id INT, name STRING, PRIMARY KEY (id, name)}), 
    EDGE Knows (Person)-[LABEL Knows {MULTIEDGE KEY()}]->(Person) 
}
'''

'''
// 基于图类型`pagerank_graph_type`创建临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #pagerank_graph TYPED pagerank_graph_type
'''

'''
// 直接从 CSV 文件导入数据到临时图`#pagerank_graph`
USE #pagerank_graph IMPORT INTO GRAPH
  { 
    NODE (v@Person {id: u_id, name: u_name}) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_node.csv", 
        FORMAT: "CSV", 
        DELIMITER: ',' 
    }, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_edge.csv", 
        FORMAT: "CSV", 
        DELIMITER: ',' 
    } 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false} 
'''

'''
// 验证临时图的统计数据
USE #pagerank_graph SHOW STATS
'''

也可以使用文件变量导入 CSV 文件:

'''
FILE node_file { u_id INT, u_name STRING } = DATAFILE { 
    PATH: "file:///tmp/test/pagerank_node.csv", 
    FORMAT: "CSV",
    DELIMITER: ','
}
FILE edge_file { src_id INT, dst_id INT, src_name STRING, dst_name STRING } = DATAFILE {
    PATH: "file:///tmp/test/pagerank_edge.csv",
    FORMAT: "CSV",
    DELIMITER: ','
}
USE #pagerank_graph IMPORT INTO GRAPH { 
    NODE (v@Person {id: u_id, name: u_name}) FROM node_file, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM edge_file 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false}
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 4         |
| Edge Total | Edge         | 5         |
+------------+--------------+-----------+

从 Parquet 文件导入

Apache Parquet 是一种广泛用于大数据分析的列式存储格式。以下示例演示如何从 Parquet 文件导入数据。

假设 Parquet 文件具有以下 schema 和数据:

  • pagerank_node.parquet:包含列u_id(INT)和u_name(STRING)。

    u_id u_name
    1 Alice
    2 Bob
    3 Carol
    4 Dave
  • pagerank_edge.parquet:包含列src_id(INT)、dst_id(INT)、src_name(STRING)和dst_name(STRING)。

    src_id dst_id src_name dst_name
    1 2 Alice Bob
    1 3 Alice Carol
    2 4 Bob Dave
    3 4 Carol Dave
    4 1 Dave Alice
'''
// 创建图类型
CREATE GRAPH TYPE IF NOT EXISTS pagerank_parquet_type AS { 
    NODE Person (LABEL Person {id INT, name STRING, PRIMARY KEY (id, name)}), 
    EDGE Knows (Person)-[LABEL Knows {MULTIEDGE KEY()}]->(Person) 
}
'''

'''
// 创建临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #pagerank_parquet TYPED pagerank_parquet_type
'''

'''
// 从 Parquet 文件导入数据
USE #pagerank_parquet IMPORT INTO GRAPH 
  { 
    NODE (v@Person {id: u_id, name: u_name}) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_node.parquet", 
        FORMAT: "PARQUET"
    }, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_edge.parquet", 
        FORMAT: "PARQUET"
    } 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false} 
'''

'''
// 验证临时图的统计数据
USE #pagerank_parquet SHOW STATS 
'''

也可以使用文件变量导入 Parquet 文件:

'''
FILE node_file { u_id INT, u_name STRING } = DATAFILE { 
    PATH: "file:///tmp/test/pagerank_node.parquet", 
    FORMAT: "PARQUET"
}
FILE edge_file { src_id INT, dst_id INT, src_name STRING, dst_name STRING } = DATAFILE {
    PATH: "file:///tmp/test/pagerank_edge.parquet",
    FORMAT: "PARQUET"
}
USE #pagerank_parquet IMPORT INTO GRAPH { 
    NODE (v@Person {id: u_id, name: u_name}) FROM node_file, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM edge_file 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false}
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 4         |
| Edge Total | Edge         | 5         |
+------------+--------------+-----------+

从 ORC 文件导入

Apache ORC 是一种针对大规模数据处理优化的列式存储格式。以下示例演示如何从 ORC 文件导入数据。

假设 ORC 文件具有以下 schema 和数据:

  • pagerank_node.orc:包含列u_id(INT)和u_name(STRING)。

    u_id u_name
    1 Alice
    2 Bob
    3 Carol
    4 Dave
  • pagerank_edge.orc:包含列src_id(INT)、dst_id(INT)、src_name(STRING)和dst_name(STRING)。

    src_id dst_id src_name dst_name
    1 2 Alice Bob
    1 3 Alice Carol
    2 4 Bob Dave
    3 4 Carol Dave
    4 1 Dave Alice
'''
// 创建图类型
CREATE GRAPH TYPE IF NOT EXISTS pagerank_orc_type AS { 
    NODE Person (LABEL Person {id INT, name STRING, PRIMARY KEY (id, name)}), 
    EDGE Knows (Person)-[LABEL Knows {MULTIEDGE KEY()}]->(Person) 
}
'''

'''
// 创建临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #pagerank_orc TYPED pagerank_orc_type
'''

'''
// 从 ORC 文件导入数据
USE #pagerank_orc IMPORT INTO GRAPH 
  { 
    NODE (v@Person {id: u_id, name: u_name}) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_node.orc", 
        FORMAT: "ORC"
    }, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM DATAFILE { 
        PATH: "file:///tmp/test/pagerank_edge.orc", 
        FORMAT: "ORC"
    } 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false} 
'''

'''
// 验证临时图的统计数据
USE #pagerank_orc SHOW STATS 
'''

也可以使用文件变量导入 ORC 文件:

'''
FILE node_file { u_id INT, u_name STRING } = DATAFILE { 
    PATH: "file:///tmp/test/pagerank_node.orc", 
    FORMAT: "ORC"
}
FILE edge_file { src_id INT, dst_id INT, src_name STRING, dst_name STRING } = DATAFILE {
    PATH: "file:///tmp/test/pagerank_edge.orc",
    FORMAT: "ORC"
}
USE #pagerank_orc IMPORT INTO GRAPH { 
    NODE (v@Person {id: u_id, name: u_name}) FROM node_file, 
    EDGE (id: src_id, name: src_name)-[e@Knows{}]->(id: dst_id, name: dst_name) FROM edge_file 
  } OPTIONS {PRIMARY_KEY_AS_NODE_ID:false}
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 4         |
| Edge Total | Edge         | 5         |
+------------+--------------+-----------+

从表变量导入数据

您可以将表变量中的数据导入到临时图中。当您需要直接从查询结果或字面量构造图数据,而不希望将数据写入外部文件时,可使用此方式。

'''
// 创建名为 movie_type_local_table 的图类型,包含带 MULTIEDGE KEY() 约束的边类型
CREATE GRAPH TYPE IF NOT EXISTS movie_type_local_table AS {
    NODE Actor (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}),
    NODE Director (LABEL Person {id INT64, name STRING, birthDate DATE, PRIMARY KEY (id)}),
    NODE `User` (LABEL Person {id INT64 PRIMARY KEY}),
    NODE Movie (LABEL Movie {id INT64 PRIMARY KEY, name STRING}),
    NODE Genre (LABEL Genre {id INT64 PRIMARY KEY, name STRING}),
    EDGE Act (Actor)-[:Act {MULTIEDGE KEY()}]->(Movie)
}
'''

'''
// 基于图类型 movie_type_local_table 创建临时图
CREATE TEMPORARY GRAPH IF NOT EXISTS #movie_local_table TYPED movie_type_local_table
'''

'''
// 从表变量导入数据
USE #movie_local_table {
  TABLE actors TYPED TABLE {id INT64, name STRING, birthDate DATE} =
    {id: 1, name: "Tom Hanks", birthDate: date("1956-07-09")},
    {id: 2, name: "Morgan Freeman", birthDate: date("1937-06-01")},
    {id: 3, name: "Tim Robbins", birthDate: date("1958-10-16")} 

  TABLE directors TYPED TABLE {id INT64, name STRING, birthDate DATE} =
    {id: 101, name: "Frank Darabont", birthDate: date("1959-01-28")},
    {id: 102, name: "Robert Zemeckis", birthDate: date("1952-05-14")} 

  TABLE users TYPED TABLE {id INT64} =
    {id: 1001},
    {id: 1002} 

  TABLE movies TYPED TABLE {id INT64, name STRING} =
    {id: 201, name: "The Shawshank Redemption"},
    {id: 202, name: "Forrest Gump"},
    {id: 203, name: "Se7en"}

  TABLE genres TYPED TABLE {id INT64, name STRING} =
    {id: 301, name: "Drama"},
    {id: 302, name: "Crime"}

  TABLE act_edges TYPED TABLE {src_id INT64, dst_id INT64} =
    {src_id: 1, dst_id: 202},
    {src_id: 2, dst_id: 201},
    {src_id: 2, dst_id: 203},
    {src_id: 3, dst_id: 201}

  IMPORT INTO GRAPH {
    NODE (a@Actor{ id: id, name: name, birthDate: birthDate }) FROM actors,
    NODE (d@Director{ id: id, name: name, birthDate: birthDate }) FROM directors,
    NODE (u@`User`{ id: id }) FROM users,
    NODE (m@Movie{ id: id, name: name }) FROM movies,
    NODE (g@Genre{ id: id, name: name }) FROM genres,
    EDGE (id:src_id)-[e@Act{}]->(id:dst_id) FROM act_edges
  } 
}
'''

'''
// 验证临时图的统计数据
USE #movie_local_table SHOW STATS
'''

返回:

+------------+--------------+-----------+
| entry_name | element_type | total_num |
+------------+--------------+-----------+
| Node Total | Node         | 12        |
| Edge Total | Edge         | 4         |
| Actor      | Node         | 3         |
| Director   | Node         | 2         |
| User       | Node         | 2         |
| Movie      | Node         | 3         |
| Genre      | Node         | 2         |
| Act        | Edge         | 4         |
+------------+--------------+-----------+