图数据库概念 #

一、图数据库概述 #

图数据库是一种以图结构存储和查询数据的数据库,由顶点(Vertex)和边(Edge)组成。

1.1 图结构 #

text
┌─────────────────────────────────────────────────────────┐
│                    图结构示例                            │
├─────────────────────────────────────────────────────────┤
│                                                         │
│    ┌───────┐  关注   ┌───────┐  关注   ┌───────┐       │
│    │ 用户A │────────▶│ 用户B │────────▶│ 用户C │       │
│    └───────┘         └───────┘         └───────┘       │
│        │                 │                             │
│        │ 购买            │ 评论                        │
│        ▼                 ▼                             │
│    ┌───────┐         ┌───────┐                         │
│    │ 商品D │         │ 文章E │                         │
│    └───────┘         └───────┘                         │
│                                                         │
│    顶点(Vertex) = 实体    边(Edge) = 关系              │
└─────────────────────────────────────────────────────────┘

1.2 核心概念 #

概念 说明 对应集合
顶点(Vertex) 图中的实体节点 文档集合
边(Edge) 连接顶点的关系 边集合
图(Graph) 顶点和边的集合 图定义

1.3 图数据库优势 #

优势 说明
关系表达 天然表达实体间关系
高效遍历 快速查询多跳关系
灵活扩展 轻松添加新的关系类型
直观建模 接近现实世界的建模方式

二、顶点(Vertex) #

2.1 顶点定义 #

顶点是图中的实体节点,存储实体的属性信息:

json
{
    "_key": "user_001",
    "_id": "users/user_001",
    "name": "张三",
    "email": "zhangsan@example.com",
    "age": 28
}

2.2 顶点集合 #

顶点存储在普通的文档集合中:

javascript
db._create("users");
db._create("products");
db._create("posts");

2.3 顶点类型 #

text
社交网络图
├── 用户顶点
│   ├── 用户A
│   ├── 用户B
│   └── 用户C
├── 商品顶点
│   ├── 商品1
│   └── 商品2
└── 文章顶点
    ├── 文章1
    └── 文章2

三、边(Edge) #

3.1 边定义 #

边连接两个顶点,表示它们之间的关系:

json
{
    "_key": "follow_001",
    "_id": "follows/follow_001",
    "_from": "users/user_001",
    "_to": "users/user_002",
    "createdAt": "2024-01-15T10:30:00Z",
    "type": "friend"
}

3.2 边属性 #

属性 说明
_from 边的起点顶点_id
_to 边的终点顶点_id
其他属性 关系的附加信息

3.3 边集合 #

边存储在边集合中:

javascript
db._createEdgeCollection("follows");
db._createEdgeCollection("purchased");
db._createEdgeCollection("commented");

3.4 边的方向 #

text
有向边:
用户A ──关注──▶ 用户B

_from: "users/userA"
_to: "users/userB"

3.5 边类型 #

text
社交网络边类型
├── 关注关系
│   └── 用户A 关注 用户B
├── 购买关系
│   └── 用户A 购买 商品1
├── 评论关系
│   └── 用户A 评论 文章1
└── 好友关系
    └── 用户A 好友 用户B

四、图定义 #

4.1 创建图 #

JavaScript创建:

javascript
var graph = db._createGraph("social", {
    edgeDefinitions: [
        {
            collection: "follows",
            from: ["users"],
            to: ["users"]
        },
        {
            collection: "purchased",
            from: ["users"],
            to: ["products"]
        }
    ]
});

4.2 图结构 #

json
{
    "name": "social",
    "edgeDefinitions": [
        {
            "collection": "follows",
            "from": ["users"],
            "to": ["users"]
        }
    ],
    "orphanCollections": []
}

4.3 边定义 #

边定义指定了边集合可以连接的顶点集合:

javascript
{
    collection: "follows",
    from: ["users"],
    to: ["users"]
}

4.4 查看图 #

javascript
db._graphs.toArray();

4.5 删除图 #

javascript
db._graph("social").drop();

五、图遍历 #

5.1 遍历方向 #

方向 说明
OUTBOUND 从_from到_to方向
INBOUND 从_to到_from方向
ANY 双向遍历

5.2 遍历语法 #

aql
FOR v, e, p IN min..max DIRECTION startVertex edgeCollection
    RETURN { vertex: v, edge: e, path: p }

5.3 遍历变量 #

变量 说明
v 当前顶点
e 当前边
p 完整路径

5.4 路径结构 #

json
{
    "vertices": [
        { "_id": "users/user_001", "name": "张三" },
        { "_id": "users/user_002", "name": "李四" }
    ],
    "edges": [
        { "_id": "follows/follow_001", "type": "friend" }
    ]
}

六、图遍历示例 #

6.1 一跳遍历 #

查找用户A关注的人:

aql
FOR v IN 1..1 OUTBOUND "users/user_001" follows
    RETURN v.name

6.2 多跳遍历 #

查找用户A的朋友的朋友:

aql
FOR v IN 2..2 OUTBOUND "users/user_001" follows
    RETURN v.name

6.3 范围遍历 #

查找1-3跳内的所有用户:

aql
FOR v, e, p IN 1..3 OUTBOUND "users/user_001" follows
    RETURN {
        name: v.name,
        depth: LENGTH(p.edges),
        path: p.vertices[*].name
    }

6.4 双向遍历 #

查找用户A的所有关注者和被关注者:

aql
FOR v, e IN ANY "users/user_001" follows
    RETURN {
        name: v.name,
        direction: e._from == "users/user_001" ? "following" : "follower"
    }

6.5 入边遍历 #

查找关注用户A的人:

aql
FOR v IN 1..1 INBOUND "users/user_001" follows
    RETURN v.name

七、图查询进阶 #

7.1 带过滤的遍历 #

aql
FOR v, e, p IN 1..3 OUTBOUND "users/user_001" follows
    FILTER v.status == "active"
    FILTER e.type == "friend"
    RETURN v.name

7.2 带限制的遍历 #

aql
FOR v IN 1..2 OUTBOUND "users/user_001" follows
    LIMIT 10
    RETURN v.name

7.3 路径去重 #

aql
FOR v, e, p IN 1..3 OUTBOUND "users/user_001" follows
    OPTIONS { uniqueVertices: "global" }
    RETURN v.name

7.4 遍历选项 #

选项 说明
uniqueVertices 顶点去重策略
uniqueEdges 边去重策略
bfs 广度优先搜索
parallelism 并行度

7.5 广度优先搜索 #

aql
FOR v IN 1..3 OUTBOUND "users/user_001" follows
    OPTIONS { bfs: true, uniqueVertices: "global" }
    RETURN v.name

八、图算法 #

8.1 最短路径 #

aql
FOR v, e IN OUTBOUND K_SHORTEST_PATHS "users/user_001" TO "users/user_005" follows
    RETURN {
        vertices: v,
        edges: e
    }

8.2 全对最短路径 #

aql
FOR source IN users
    FOR target IN users
        FILTER source._key != target._key
        LET path = (
            FOR v, e IN OUTBOUND K_SHORTEST_PATHS source TO target follows
                LIMIT 1
                RETURN LENGTH(e)
        )[0]
        RETURN {
            from: source.name,
            to: target.name,
            distance: path
        }

8.3 k-shortest路径 #

aql
FOR p IN OUTBOUND K_PATHS "users/user_001" TO "users/user_005" follows
    LIMIT 3
    RETURN p

九、图数据库应用场景 #

9.1 社交网络 #

text
社交网络图
├── 顶点
│   ├── 用户
│   ├── 群组
│   └── 话题
└── 边
    ├── 关注
    ├── 加入
    └── 发布

9.2 知识图谱 #

text
知识图谱
├── 顶点
│   ├── 概念
│   ├── 实体
│   └── 属性
└── 边
    ├── 是一种
    ├── 包含
    └── 相关

9.3 推荐系统 #

text
推荐系统图
├── 顶点
│   ├── 用户
│   ├── 商品
│   └── 标签
└── 边
    ├── 购买
    ├── 浏览
    └── 标记

9.4 欺诈检测 #

text
欺诈检测图
├── 顶点
│   ├── 账户
│   ├── 设备
│   └── 交易
└── 边
    ├── 使用
    ├── 转账
    └── 关联

十、图设计最佳实践 #

10.1 顶点设计 #

text
原则:
├── 顶点代表实体
├── 属性存储实体信息
├── 避免过度嵌套
└── 合理设置_id

10.2 边设计 #

text
原则:
├── 边代表关系
├── 方向要有意义
├── 属性存储关系信息
└── 合理命名边类型

10.3 索引设计 #

javascript
db.follows.ensureHashIndex(["_from"]);
db.follows.ensureHashIndex(["_to"]);

10.4 性能优化 #

text
优化建议:
├── 限制遍历深度
├── 使用过滤条件
├── 设置遍历选项
└── 合理使用索引

十一、总结 #

图数据库核心概念:

  1. 顶点:图中的实体节点
  2. :连接顶点的关系
  3. :顶点和边的集合
  4. 遍历:在图中导航查询
  5. 方向:OUTBOUND、INBOUND、ANY

下一步,让我们学习边集合与顶点操作!

最后更新:2026-03-27