仅需一个插件让关系型数据库实现图数据存储与检索

简介

Apache AGE是一个PostgreSQL数据库的扩展插件,使得在关系型数据库中也可以使用openCypher查询语言进行图查询。有了该插件,可以在PostgreSQL数据库中同时实现关键字检索、向量检索、图检索,仅需一个数据库即可实现复杂RAG的各种存储和检索需求。

安装

Docker安装

  1. 获取镜像
docker pull apache/age
  1. 运行容器
docker run \
    --name age  \
    -p 5455:5432 \
    -e POSTGRES_USER=postgresUser \
    -e POSTGRES_PASSWORD=postgresPW \
    -e POSTGRES_DB=postgresDB \
    -d \
    apache/age
  1. 启动数据库
docker exec -it age psql -d postgresDB -U postgresUser

源码安装

Git Clone仓库或手动下载官方发布的版本。目前,仅支持 PostgreSQL 版本 11~16,若低于11则无法安装使用。

安装及初始化

  1. 安装扩展
CREATE EXTENSION age;
  1. 加载扩展
LOAD 'age';
  1. 设置搜索路径
SET search_path = ag_catalog, "$user", public;
  1. 创建图
SELECT create_graph('my_graph');

AGE这个插件与其他插件不同,安装后,还需要执行第二步加载插件和第三步设置搜索路径。设置搜索路径则是为了让数据库能够找到 AGE 的函数,如 create_graph(),否则执行相关函数都会出错

基本操作

基本创建操作

创建节点

  1. 创建单个节点
SELECT * FROM cypher('my_graph', $$
    CREATE (p:Person {name: '张三', age: 30})
    RETURN p
$$) as (v agtype);
  1. 同时创建多个节点
SELECT * FROM cypher('my_graph', $$
    CREATE (p1:Person {name: '李四', age: 25}),
           (p2:Person {name: '王五', age: 35})
    RETURN p1, p2
$$) as (v1 agtype, v2 agtype);

创建边

  1. 根据已有的节点创建边
SELECT * FROM cypher('my_graph', $$ 
    MATCH (p1:Person {name: '李四'}), (p2:Person {name: '王五'}) 
    CREATE (p1)-[r:FRIEND]->(p2) 
$$
) AS (e agtype);
  1. 创建边的同时创建节点
SELECT * FROM cypher('my_graph', $$
    CREATE (a:Person {name: 'Alice', age: 30})-[:FRIEND]->(b:Person {name: 'Bob', age: 27})
$$
) AS (result agtype);

基本查询操作

查询节点

# 查询所有Person节点
SELECT * FROM cypher('my_graph', $$
    MATCH (p:Person)
    RETURN p
$$) as (v agtype);

# 条件查询节点
SELECT * FROM cypher('my_graph', $$
    MATCH (p:Person)
    WHERE p.age > 30
    RETURN p
$$) as (v agtype);

查询边

# 查询所有朋友关系
SELECT * FROM cypher('my_graph', $$
    MATCH (a:Person)-[r:FRIENDS]->(b:Person)
    RETURN a.name, r.since, b.name
$$) as (name1 agtype, since agtype, name2 agtype);

# 查询特定条件的关系
SELECT * FROM cypher('my_graph', $$
    MATCH (a:Person)-[r:WORKS_AT]->(c:Company)
    WHERE c.name = '科技公司'
    RETURN a.name, c.name
$$) as (person_name agtype, company_name agtype);

高级查询功能

路径查询

# 查找两个节点之间的路径
SELECT * FROM cypher('my_graph', $$
    MATCH p = (a:Person {name: '张三'})-[*1..3]->(b:Person)
    RETURN p
$$) as (path agtype);
*表示任意边,范围在13之间的节点

聚合查询

# 统计每个公司的员工数
SELECT * FROM cypher('my_graph', $$
    MATCH (p:Person)-[:WORKS_AT]->(c:Company)
    RETURN c.name, count(p) as employee_count
$$) as (company agtype, count agtype);

基本更新操作

更新节点

# 更新节点属性
SELECT * FROM cypher('my_graph', $$
    MATCH (p:Person {name: '张三'})
    SET p.age = 31
    RETURN p
$$) as (v agtype);

删除边

# 删除关系
SELECT * FROM cypher('my_graph', $$
    MATCH (a:Person)-[r:FRIENDS]->(b:Person)
    WHERE a.name = '张三' AND b.name = '李四'
    DELETE r
$$) as (v agtype);

删除节点

# 删除节点(需要先删除相关的边)
SELECT * FROM cypher('my_graph', $$
    MATCH (p:Person {name: '张三'})
    DETACH DELETE p
$$) as (v agtype);

索引

Age支持对节点和边构建索引,用于加速查找过程。

节点索引

# 1. 基本的 B-tree 索引(适用于等值查询、范围查询)
CREATE INDEX idx_person_name ON ag_catalog.ag_label_vertex 
USING btree ((properties -> 'name')) 
WHERE label = 'Person' AND graph_name = 'my_graph';

# 2. GiST 索引(适用于地理数据或多维数据)
CREATE INDEX idx_person_location ON ag_catalog.ag_label_vertex 
USING gist ((properties -> 'location')) 
WHERE label = 'Person' AND graph_name = 'my_graph';

# 3. Hash 索引(仅适用于等值查询)
CREATE INDEX idx_person_id ON ag_catalog.ag_label_vertex 
USING hash ((properties -> 'id')) 
WHERE label = 'Person' AND graph_name = 'my_graph';

# 4. 多列索引
CREATE INDEX idx_person_name_age ON ag_catalog.ag_label_vertex 
USING btree ((properties -> 'name'), (properties -> 'age')) 
WHERE label = 'Person' AND graph_name = 'my_graph';

边索引

# 1. 基本的关系索引
CREATE INDEX idx_friendship_date ON ag_catalog.ag_label_edge 
USING btree ((properties -> 'since')) 
WHERE label = 'FRIENDS' AND graph_name = 'my_graph';

# 2. 复合边索引
CREATE INDEX idx_relationship_composite ON ag_catalog.ag_label_edge 
USING btree ((properties -> 'type'), (properties -> 'weight')) 
WHERE label = 'RELATIONSHIP' AND graph_name = 'my_graph';

索引管理

# 查看所有索引
SELECT * FROM pg_indexes 
WHERE tablename LIKE 'ag_label%';

# 删除索引
DROP INDEX IF EXISTS idx_person_name;

# 重建索引
REINDEX INDEX idx_person_name;

其他功能

查询已创建的图

# 使用 ag_catalog.ag_graph 表查询
SELECT * FROM ag_catalog.ag_graph;

总结

对于生产环境来说,PostgreSQL是最常用的数据库之一,有了Age这个插件,可以无缝为传统的RAG知识库服务提供图检索能力,真正做到All in one,同时也无需担心额外增加图数据库引入的复杂性和兼容问题。

posted @   深度学习机器  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示