简介
图由顶点(Vertices) 和 边(edges)组成。ArangoDB中,除了有顶点的collections, 还有边的collections,边会在边的collections中存储为一个个documents。
ArangoDB中有两种collection; > 分别是 edge collection 和 document collection > 顶点可以是document collection中的document,或者是edge collection的document,因此边可以用作顶点
图是什么?
在SQL世界中,针对n:m的关系(多对多),通常会为该关系单独建立一张表,从而将相应的两个数据表建立联系。ArangoDB中的 edge collection
类似这种概念,而 vertex collection
或者叫document collection,类似于SQL中的数据表,里面存放的是想被联系的数据。
在SQL中想查询小王的朋友的朋友这种问题,虽然可以通过多次join来实现,但在图中,这仅仅代表从小王这个点出发,进行两跳(hops),该过程称为图遍历(graph traversal)。
在有向图中,边是有方向的,分别从vertex collection
中的一个document指向另一个document,用 _from
和 _to
表示方向。在编写查询的时候,可以指明边的方向,比如OUTBOUND
: _from
→ _to
,
INBOUND
: _from
← _to
,
ANY
: _from
↔ _to
ArangoDB支持哪些图算法
图遍历
- 沿着outbound, inbound或任意方向遍历边
- 在指定的深度范围(traversal depth)内遍历
- 深度优先、广度优先、带权重遍历
- 可配合剪枝条件
最短路径
例如我们使用高德、百度地图导航时,两个点之间的最短路径
k个最短路径
k个路径
Distributed Iterative Graph Processing (Pregel)
- Page Rank
- Seeded Page Rank
- Single-Source Shortest Path (SSSP)
- Connected Components
- Weakly Connected Components(WCC)
- Strongly Connected Components (SCC)
- Hyperlink-Induced Topic Search (HITS)
- Effective Closeness Vertex Centrality
- LineRank Vertex Centrality
- Label Propagation Community Detection
- Speaker-Listener Label Propagation (SLPA) Community Detection
- Programmable Pregel Algorithms (experimental)
命名图和匿名图
命名图(Named Graphs)完全由ArangoDB来管理,可以在web界面中看到,拥有ArangoDB中全部的图特性,在ArangoDB中,通过叫graph module
的层来提供以下保证:
- 所有修改都是事务性的
- 如果删除一个顶点,所有相邻的边也被删除
- 如果插入一条边,则会检查该边是否与边的定义匹配
如果你没有通过graph module
来访问对应的collections,则以上的所有保证都将失去,这时候,你的操作可能会导致数据不一致,在图中表现为悬空边(dangling edges)之类的问题。
匿名图(Anonymous Graphs),没有相应的边定义来描述哪个vertex collection
由哪个 edge collection
来连接。
该选择哪种图呢?
如上所述,命名图在插入或删除边或顶点时确保图的完整性。因此,即使你在多个命名图中使用相同的vertex collection
,也不会遇到悬空边。但这涉及到数据库内部的更多操作,这些操作都是有代价的。
因此,匿名图可能更快。 因此这个问题是一种权衡,性能和完整性之间找到一个平衡点。
如何确定点和边
在建立图时,首先会面临一个问题,我的数据中哪些应该作为图中的点,哪些是边? 有一个能帮助思考的方法是:首先用简短的句子描述业务场景,其中的名词可以当做点,动词当做边。
比如说我们有用户和其所属组织的数据,那么一个业务场景就是: 查询某个用户(名词)属于(动词)哪些组织(名词)呢?
因此我们可以确定两类型顶点 Users 和 Groups
,在ArangoDB中可以使用两个不同的 vertex collections
来保存, Groups collection中可以存储组织的一些属性,比如组织的名称、成立日期,组织的URL等;同理,Users collection中可以存储用户的姓名、生日、性别等属性。
用户和组织之间的所属关系,我们可以用边来联系,逻辑上,二者之间是多对多(m:n)的关系,如果是在SQL中,我们会建立一个单独的关系表用外键来存储对应关系;在ArangoDB图数据库中,我们会使用一个edge collection,比如叫做UsersInGroups
的collection来存储从属关系,例如其中一条边可以是:_from指向Users/John,_to指向Groups/BowlingGroupHappyPin
,形成的关系如下图所示。
同样也可以为该关系添加属性,比如从何时起加入的该组织(e.g., since: 2022-4-12),组织中担任的角色(role: member)
相较于RDBMS中的存储方式,使用图可以更直观的看到不同实体之间的关系,更利于对数据进行深入分析并建模。尤其是当涉及到多跳(hops)的场景时,图的优势更明显。
备份还原
可以使用arangodump备份,使用arangorestore将备份还原到一个新的ArangoDB。
需要注意两点:
- 若要备份命名图,需使用system collection
_graphs
- 需要备份图包含的完整边和点,部分备份还原可能无法工作
图示例
ArangoDB自带了一些示例,帮助理解图及其APIs, 本文只列举其中的几个示例。
Knows_Graph
该示例中,只有一种节点(persons)和一种关系(KNOWS),5个人之间的关系如图所示,箭头的方向代表关系(KNOWS)的方向
- Alice knows Bob
- Bob knows Charlie
- Bob knows Dave
- Eve knows Alice
- Eve knows Bob
Social Graph
该图中有两类节点,分别是 female
and male
,人之间的关系存储在 relation
collection中