全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

将数据库表的数据写入 AGE

最近更新时间:2025-11-11 16:29:40

在处理已有业务数据或大规模数据场景时,若采用 CREATE 语法逐条插入节点和边,将导致性能极低。为提高效率,建议先将原始数据导入至关系型表中,再通过以下步骤批量写入图分析引擎(AGE)。

以下示例基于前文 创建与使用 AGE 图分析引擎 中的模型,假设包含以下三个节点:

  • Catalog

  • Collection

  • Item

以及两种关系:

  • BELONGS_TO:表示 Collection 属于 Catalog

  • PART_OF:表示 Item 属于 Collection

接下来,我们将演示如何从关系表批量导入这些节点与边到 AGE 图中。


步骤一:创建数据表并写入原始数据

在将数据导入 AGE 图分析引擎之前,首先需要在关系型数据库中创建原始数据表,用于存放节点和关系数据。以下示例分别创建 CatalogCollectionItem 三类节点表,以及 BELONGS_TOPART_OF 两类关系表,并插入示例数据。

  1. 创建 Catalog 表(用于存储 Catalog 数据)并写入样本数据:

CREATE TABLE IF NOT EXISTS catalog_raw (
    id BIGINT,
    code TEXT,
    name TEXT,
    description TEXT
);

INSERT INTO catalog_raw VALUES
('0', 'C001', 'Apparel Catalog', 'Fashion and clothing catalog'),
('1', 'C002', 'Electronics Catalog', 'Electronic devices and accessories');
  1. 创建 Collection 表(用于存放 Collection 数据)并写入样本数据:

CREATE TABLE IF NOT EXISTS collection_raw (
    id BIGINT,
    code TEXT,
    name TEXT,
    season TEXT
);

INSERT INTO collection_raw VALUES
('10', 'SS22', 'Spring Summer 2022', 'Spring'),
('11', 'FW22', 'Fall Winter 2022', 'Fall'),
('12', 'SS23', 'Spring Summer 2023', 'Spring');
  1. 创建 Item 表(用于存放 Item 数据)并写入样本数据:

CREATE TABLE IF NOT EXISTS item_raw (
    id BIGINT,
    code TEXT,
    name TEXT,
    price DECIMAL
);

INSERT INTO item_raw VALUES
('100', 'ISS001', 'T-Shirt', 29.99),
('101', 'ISS002', 'Jeans', 79.99),
('102', 'ISS003', 'Sneakers', 129.99),
('103', 'IWS001', 'Winter Coat', 199.99),
('104', 'IWS002', 'Boots', 149.99);

该表用于存储商品(Item)信息,字段说明如下:

  • id:唯一标识符

  • code:商品代码

  • name:商品名称

  • price:商品价格

  1. 创建 BELONGS_TO 表(用于存放 CollectionCatalog 的关系数据)并写入样本数据:

CREATE TABLE IF NOT EXISTS collection_belongsto_catalog_raw (
    start_id BIGINT,
    end_id BIGINT
);

INSERT INTO collection_belongsto_catalog_raw VALUES ('10','0'), ('11','0'), ('12','0');

该表定义了 Collection → Catalog 的从属关系(BELONGS_TO),即每个系列所属的目录。

  1. 创建 PART_OF 表(用于存放 ItemCollection 的关系数据)并写入样本数据。

CREATE TABLE IF NOT EXISTS item_partof_collection_raw (
    start_id BIGINT,
    end_id BIGINT
);

INSERT INTO item_partof_collection_raw VALUES ('100','10'), ('101','10'), ('102','10'), ('103','11'), ('104','11');

该表定义了 Item → Collection 的归属关系(PART_OF),表示每个商品所属的系列。


步骤二:创建辅助函数

在批量将关系表数据写入 AGE 图结构前,需要创建两个辅助函数,用于生成节点和边的唯一标识符(ID)及序列号。这些函数将帮助 AGE 在导入过程中保持 ID 的唯一性和一致性。

  1. 创建辅助函数 age_name_to_idx_start。该函数根据图名称、对象类型(节点或边)及标签名称生成唯一的 ID 起始值。

CREATE OR REPLACE FUNCTION age_name_to_idx_start(graph_name text, kind_name text, label_name text)
  RETURNS bigint
  AS 'SELECT id::bigint<<48 FROM ag_catalog.ag_label WHERE kind = kind_name AND name = label_name AND graph = (SELECT graphid FROM ag_catalog.ag_graph WHERE name = graph_name)'
  LANGUAGE SQL IMMUTABLE STRICT PARALLEL SAFE;
  1. 创建函数 age_name_to_seq。该函数用于返回节点或边对应的内部自增序列名称,用于生成后续插入时的唯一 ID。

CREATE OR REPLACE FUNCTION age_name_to_seq(graph_name text, kind_name text, label_name text)
  RETURNS text
  AS $$SELECT graph_name || '."' || seq_name || '"' FROM ag_catalog.ag_label WHERE kind = kind_name and name = label_name and graph = (SELECT graphid FROM ag_catalog.ag_graph WHERE name = graph_name)$$
  LANGUAGE SQL IMMUTABLE STRICT PARALLEL SAFE;

参数说明

  • graph_name:图名称。

  • kind_name:类型(v 表示节点,e 表示边)。

  • label_name:标签名称。

这两个函数在后续写入阶段会被用来自动生成节点和边的唯一标识。


步骤三:创建图、节点、边

首先,创建一个新的图对象:

SELECT ag_catalog.create_graph('playground');

然后,为该图定义所需的节点标签(Vertex Label)和边标签(Edge Label):

-- 创建节点标签
SELECT ag_catalog.create_vlabel('playground', 'Catalog');
SELECT ag_catalog.create_vlabel('playground', 'Collection');
SELECT ag_catalog.create_vlabel('playground', 'Item');

-- 创建边标签
SELECT ag_catalog.create_elabel('playground', 'BELONGS_TO');
SELECT ag_catalog.create_elabel('playground', 'PART_OF');
  • 节点标签对应数据模型中的实体类型。

  • 边标签定义节点间的关联关系。

  • 标签创建完成后,AGE 会在图对应的 schema 下自动生成相应的存储表结构。


步骤四:导入节点数据

在完成图结构及辅助函数的创建后,可以将关系表中的原始数据批量导入为图中的节点数据。

以下 SQL 语句分别导入 CatalogCollectionItem 三类节点数据,并同步更新对应的序列值。

-- 导入 Catalog 数据
INSERT INTO playground."Catalog"
  SELECT 
  (age_name_to_idx_start('playground', 'v', 'Catalog') + id)::text::ag_catalog.graphid,
  row_to_json((SELECT x FROM (SELECT code, name, description) x))::text::ag_catalog.agtype 
  FROM catalog_raw;

-- 设置 Catalog 的序列值
SELECT setval(age_name_to_seq('playground', 'v', 'Catalog'), (SELECT max(id) + 1 FROM catalog_raw));


-- 导入 Collection 数据
INSERT INTO playground."Collection"
  SELECT 
  (age_name_to_idx_start('playground', 'v', 'Collection') + id)::text::ag_catalog.graphid,
  row_to_json((SELECT x FROM (SELECT code, name, season) x))::text::ag_catalog.agtype 
  FROM collection_raw;

-- 设置 Collection 的序列值
SELECT setval(age_name_to_seq('playground', 'v', 'Collection'), (SELECT max(id) + 1 FROM collection_raw));


-- 导入 Item 数据
INSERT INTO playground."Item"
  SELECT 
  (age_name_to_idx_start('playground', 'v', 'Item') + id)::text::ag_catalog.graphid,
  row_to_json((SELECT x FROM (SELECT code, name, price) x))::text::ag_catalog.agtype 
  FROM item_raw;

-- 设置 Item 的序列值
SELECT setval(age_name_to_seq('playground', 'v', 'Item'), (SELECT max(id) + 1 FROM item_raw));

说明:

  • 每个节点表都通过 age_name_to_idx_start 计算唯一 ID,确保在同一图中不冲突。

  • row_to_json() 用于将节点属性转换为 JSON 结构,以符合 AGE 图的存储格式。

  • 通过 setval() 同步更新内部序列,保证后续插入数据时 ID 连续。


步骤五:导入边的数据

节点导入完成后,可将关系表中的关联数据导入为图中的边(Edge)。以下 SQL 语句批量创建 BELONGS_TOPART_OF 两种关系。

-- 导入BELONGS_TO边的数据
INSERT INTO playground."BELONGS_TO"(start_id,end_id,properties)
SELECT
(age_name_to_idx_start('playground', 'v', 'Collection') + start_id)::text::ag_catalog.graphid,
(age_name_to_idx_start('playground', 'v', 'Catalog') + end_id)::text::ag_catalog.graphid,
'{}'::text::ag_catalog.agtype
FROM collection_belongsto_catalog_raw;

-- 导入PART_OF边的数据
INSERT INTO playground."PART_OF"(start_id,end_id,properties)
SELECT
(age_name_to_idx_start('playground', 'v', 'Item') + start_id)::text::ag_catalog.graphid,
(age_name_to_idx_start('playground', 'v', 'Collection') + end_id)::text::ag_catalog.graphid,
'{}'::text::ag_catalog.agtype
FROM item_partof_collection_raw;

步骤六:验证数据

完成节点与边的导入后,可通过 Cypher 查询验证数据是否正确写入图中:

SELECT * FROM  ag_catalog.cypher('playground', $$
  MATCH (c:Catalog)<-[:BELONGS_TO]-(co:Collection)<-[:PART_OF]-(i:Item)
  RETURN c, co, i
  LIMIT 5
  $$) AS (catalog ag_catalog.agtype, collection ag_catalog.agtype, item ag_catalog.agtype);

文档导读
纯净模式常规模式

纯净模式

点击可全屏预览文档内容
文档反馈