5个不稳定版本
0.2.0-alpha.1 | 2024年8月1日 |
---|---|
0.1.1 | 2024年8月1日 |
0.1.0 | 2024年7月31日 |
0.0.2 | 2024年7月29日 |
0.0.1 | 2024年7月26日 |
#35 in 数据库实现
每月477次下载
250KB
6K SLoC
simple-triplestore —
一种三元组存储实现,可以作为支持自定义节点和边属性的灵活图数据库使用。
数据模型
每个顶点和边(统称为nodes
)都关联一个id(即u64
或Ulid)。
属性数据存储为
Id->NodeProps
Id->EdgeProps
.
图形关系以(Id, Id, Id) -> Id
的形式存储,以下排序顺序
- 主题,谓词,对象
- 谓词,对象,主题
- 对象,主题,谓词
这允许将任何图形查询分解为带有理想排序的查找范围查询。例如,
query!{ a -b-> ? }
成为主题-谓词-对象表的查询。query!{ ? -a-> b }
成为位置-对象-主题表的查询。query!{ a -?-> b }
成为对象-主题-位置表的查询。
支持的关键值后端
示例
引入我们需要的各种包含文件
use ulid::Ulid;
use simple_triplestore::prelude::*;
let mut db = MemTripleStore::new(UlidIdGenerator::new());
获取一些标识符。在真实的应用程序中,这些将来自索引或其他查找表。
let node_1 = Ulid(123);
let node_2 = Ulid(456);
let node_3 = Ulid(789);
let edge = Ulid(999);
插入具有用户定义属性类型的节点和边。对于给定的 TripleStore,我们可以为节点和边分别有一个类型。
db.insert_node(node_1, "foo".to_string())?;
db.insert_node(node_2, "bar".to_string())?;
db.insert_node(node_3, "baz".to_string())?;
db.insert_edge(Triple{sub: node_1, pred: edge, obj: node_2}, Vec::from([1,2,3]))?;
db.insert_edge(Triple{sub: node_1, pred: edge, obj: node_3}, Vec::from([4,5,6]))?;
现在我们可以查询以 node_3
结尾的边,并发现只有一个。
assert_eq!(
db.run(query!{ ? -?-> [node_3] })?
.iter_edges(EdgeOrder::default())
.map(|r| r.expect("ok"))
.collect::<Vec<_>>(),
[
(Triple{sub: node_1, pred: edge, obj: node_3}, Vec::from([4,5,6])),
]
);
我们还可以查询具有谓词 edge
的所有边,并找到我们添加的两个边
assert_eq!(
db.run(query!{ ? -[edge]-> ? })?
.iter_edges(EdgeOrder::default())
.map(|r| r.expect("ok"))
.collect::<Vec<_>>(),
[
(Triple{sub: node_1, pred: edge, obj: node_2}, Vec::from([1,2,3])),
(Triple{sub: node_1, pred: edge, obj: node_3}, Vec::from([4,5,6])),
]
);
依赖项
~1.8–2.7MB
~45K SLoC