Rust图数据库插件库kuzu的使用,kuzu提供高效图数据存储与查询功能
Rust图数据库插件库kuzu的使用,kuzu提供高效图数据存储与查询功能
Kuzu是一个嵌入式图数据库,专为查询速度和可扩展性而构建。Kuzu优化了处理超大型数据库上的复杂分析工作负载,并提供了一系列检索功能,如全文搜索和向量索引。核心功能包括:
- 灵活的属性图数据模型和Cypher查询语言
- 可嵌入的、无服务器的应用程序集成
- 原生全文搜索和向量索引
- 基于列的磁盘存储
- 基于列的稀疏行(CSR)邻接列表/连接索引
- 向量化和因子化查询处理器
- 新颖且非常快速的连接算法
- 多核查询并行性
- 可序列化的ACID事务
- Wasm(WebAssembly)绑定,用于在浏览器中快速安全地执行
安装
对于Rust项目,可以使用以下命令安装kuzu:
cargo add kuzu
或者在你的Cargo.toml文件中添加:
kuzu = "0.11.1"
示例代码
以下是一个完整的使用kuzu的Rust示例:
use kuzu::{Database, Connection};
fn main() {
// 创建或打开数据库
let db = Database::new("test_db").unwrap();
// 创建连接
let mut conn = Connection::new(&db).unwrap();
// 创建节点表
conn.query("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY(name))").unwrap();
// 创建关系表
conn.query("CREATE REL TABLE Knows(FROM Person TO Person, since INT64)").unwrap();
// 插入数据
conn.query("CREATE (p:Person {name: 'Alice', age: 35})").unwrap();
conn.query("CREATE (p:Person {name: 'Bob', age: 30})").unwrap();
conn.query("MATCH (a:Person), (b:Person) WHERE a.name = 'Alice' AND b.name = 'Bob' CREATE (a)-[:Knows {since: 2020}]->(b)").unwrap();
// 查询数据
let result = conn.query(
"MATCH (a:Person)-[k:Knows]->(b:Person) RETURN a.name, b.name, k.since"
).unwrap();
// 打印结果
while let Some(row) = result.next().unwrap() {
let alice_name: String = row.get(0).unwrap();
let bob_name: String = row.get(1).unwrap();
let since: i64 = row.get(2).unwrap();
println!("{} 认识 {} 从 {} 年开始", alice_name, bob_name, since);
}
}
这个示例展示了如何:
- 创建或打开一个kuzu数据库
- 创建节点表和关系表
- 插入节点和关系数据
- 执行查询并处理结果
高级特性
kuzu还支持许多高级特性,如:
// 批量插入数据
conn.query("COPY Person FROM \"data/persons.csv\" (HEADER=true)").unwrap();
// 使用参数化查询
let mut stmt = conn.prepare("MATCH (p:Person) WHERE p.age > $age RETURN p.name").unwrap();
stmt.bind("age", 30).unwrap();
let result = stmt.execute().unwrap();
// 事务处理
{
let tx = conn.begin_transaction().unwrap();
tx.query("CREATE (p:Person {name: 'Charlie', age: 25})").unwrap();
tx.commit().unwrap();
}
Kuzu由Kùzu Inc.开发,采用MIT许可协议。欢迎尝试并提供反馈和功能请求。
完整示例demo
下面是一个更完整的kuzu使用示例,展示了更多功能:
use kuzu::{Database, Connection, Error};
use std::path::Path;
fn main() -> Result<(), Error> {
// 1. 初始化数据库
let db_path = Path::new("example_db");
let db = Database::new(db_path)?;
// 2. 创建连接
let mut conn = Connection::new(&db)?;
// 3. 创建schema
// 创建节点表:用户
conn.query("CREATE NODE TABLE User(id INT64, name STRING, PRIMARY KEY(id))")?;
// 创建节点表:商品
conn.query("CREATE NODE TABLE Product(id INT64, name STRING, price FLOAT, PRIMARY KEY(id))")?;
// 创建关系表:购买
conn.query("CREATE REL TABLE Purchased(FROM User TO Product, date STRING, quantity INT64)")?;
// 4. 插入数据
// 插入用户数据
conn.query("CREATE (u:User {id: 1, name: 'Alice'})")?;
conn.query("CREATE (u:User {id: 2, name: 'Bob'})")?;
// 插入商品数据
conn.query("CREATE (p:Product {id: 101, name: 'Laptop', price: 999.99})")?;
conn.query("CREATE (p:Product {id: 102, name: 'Phone', price: 699.99})")?;
// 插入购买关系
conn.query("MATCH (u:User), (p:Product) WHERE u.id = 1 AND p.id = 101 CREATE (u)-[:Purchased {date: '2023-01-15', quantity: 1}]->(p)")?;
conn.query("MATCH (u:User), (p:Product) WHERE u.id = 2 AND p.id = 102 CREATE (u)-[:Purchased {date: '2023-01-20', quantity: 2}]->(p)")?;
// 5. 查询示例
// 简单查询
println!("--- 所有用户 ---");
let users = conn.query("MATCH (u:User) RETURN u.id, u.name")?;
while let Some(row) = users.next()? {
let id: i64 = row.get(0)?;
let name: String = row.get(1)?;
println!("用户ID: {}, 姓名: {}", id, name);
}
// 复杂查询:查找购买了特定商品的用户
println!("\n--- 购买了Laptop的用户 ---");
let laptop_buyers = conn.query(
"MATCH (u:User)-[p:Purchased]->(prod:Product)
WHERE prod.name = 'Laptop'
RETURN u.name, p.date, p.quantity"
)?;
while let Some(row) = laptop_buyers.next()? {
let name: String = row.get(0)?;
let date: String = row.get(1)?;
let qty: i64 = row.get(2)?;
println!("用户 {} 于 {} 购买了 {} 台", name, date, qty);
}
// 6. 使用事务
println!("\n--- 事务示例 ---");
{
let tx = conn.begin_transaction()?;
tx.query("CREATE (p:Product {id: 103, name: 'Tablet', price: 299.99})")?;
tx.query("MATCH (u:User), (p:Product) WHERE u.id = 1 AND p.id = 103 CREATE (u)-[:Purchased {date: '2023-02-01', quantity: 1}]->(p)")?;
tx.commit()?;
}
// 7. 参数化查询
println!("\n--- 参数化查询 ---");
let mut stmt = conn.prepare("MATCH (u:User)-[p:Purchased]->(prod:Product) WHERE p.quantity > $min_qty RETURN u.name, prod.name, p.quantity")?;
stmt.bind("min_qty", 1)?;
let high_qty_purchases = stmt.execute()?;
while let Some(row) = high_qty_purchases.next()? {
let user: String = row.get(0)?;
let product: String = row.get(1)?;
let qty: i64 = row.get(2)?;
println!("用户 {} 购买了 {} (数量: {})", user, product, qty);
}
Ok(())
}
这个完整示例展示了:
- 数据库初始化和连接创建
- 创建节点表和关系表
- 插入节点和关系数据
- 简单查询和复杂查询
- 事务处理
- 参数化查询
所有操作都包含错误处理,使用了Rust的Result类型。
1 回复
Rust图数据库插件库kuzu的使用指南
介绍
kuzu是一个高效的图数据库插件库,专为Rust设计,提供了强大的图数据存储和查询功能。它特别适合需要处理复杂关系数据的应用场景,如社交网络分析、推荐系统、知识图谱等。
kuzu的主要特点包括:
- 高性能的图数据存储引擎
- 支持复杂的图查询操作
- 内存优化的数据结构
- 简洁易用的Rust API接口
安装方法
在Cargo.toml中添加依赖:
[dependencies]
kuzu = "0.1.0" # 请检查最新版本号
基本使用方法
1. 创建数据库和连接
use kuzu::{Database, Connection};
fn main() {
// 创建或打开数据库
let db = Database::new("test_db").unwrap();
// 建立连接
let conn = Connection::new(&db).unwrap();
}
2. 定义节点和关系模式
conn.execute("CREATE NODE TABLE User(name STRING, age INT64, PRIMARY KEY (name))").unwrap();
conn.execute("CREATE NODE TABLE Post(title STRING, content STRING, PRIMARY KEY (title))").unwrap();
conn.execute("CREATE REL TABLE Follows(FROM User TO User, since INT64)").unwrap();
conn.execute("CREATE REL TABLE Wrote(FROM User TO Post)").unwrap();
3. 插入数据
conn.execute("CREATE (:User {name: 'Alice', age: 30})").unwrap();
conn.execute("CREATE (:User {name: 'Bob', age: 25})").unwrap();
conn.execute("CREATE (:Post {title: 'Hello', content: 'My first post'})").unwrap();
// 建立关系
conn.execute("MATCH (a:User {name: 'Alice'}), (b:User {name: 'Bob'}) CREATE (a)-[:Follows {since: 2020}]->(b)").unwrap();
conn.execute("MATCH (a:User {name: 'Alice'}), (p:Post {title: 'Hello'}) CREATE (a)-[:Wrote]->(p)").unwrap();
4. 基本查询
// 查询所有用户
let result = conn.execute("MATCH (u:User) RETURN u.name, u.age").unwrap();
for row in result.iter() {
let name: String = row.get(0).unwrap();
let age: i64 = row.get(1).unwrap();
println!("User: {}, Age: {}", name, age);
}
// 查询Alice关注的人
let result = conn.execute(
"MATCH (a:User {name: 'Alice'})-[:Follows]->(b:User) RETURN b.name"
).unwrap();
5. 复杂图查询
// 查找Alice的朋友写的帖子
let result = conn.execute(
"MATCH (a:User {name: 'Alice'})-[:Follows]->(friend:User)-[:Wrote]->(post:Post)
RETURN friend.name, post.title, post.content"
).unwrap();
// 路径查询:查找Alice到Bob的最短路径
let result = conn.execute(
"MATCH p=shortestPath((a:User {name: 'Alice'})-[*..5]-(b:User {name: 'Bob'}))
RETURN nodes(p), relationships(p)"
).unwrap();
高级功能
批量导入数据
// 从CSV文件批量导入节点
conn.execute(
"COPY User FROM 'path/to/users.csv' (HEADER=true)"
).unwrap();
// 从CSV文件批量导入关系
conn.execute(
"COPY Follows FROM 'path/to/follows.csv' (HEADER=true)
").unwrap();
事务处理
// 开始事务
let tx = conn.begin_transaction().unwrap();
// 在事务中执行操作
tx.execute("CREATE (:User {name: 'Charlie', age: 28})").unwrap();
tx.execute("MATCH (a:User {name: 'Alice'}), (c:User {name: 'Charlie'}) CREATE (a)-[:Follows {since: 2023}]->(c)").unwrap();
// 提交事务
tx.commit().unwrap();
参数化查询
let mut query = conn.prepare(
"MATCH (u:User) WHERE u.age > $age RETURN u.name"
).unwrap();
query.bind("age", &35).unwrap();
let result = query.execute().unwrap();
性能优化建议
- 为常用查询属性创建索引:
conn.execute("CREATE INDEX ON :User(name)").unwrap();
-
对于大型图,考虑分批处理查询结果
-
使用参数化查询避免重复解析查询语句
-
合理设计图模式,避免过度复杂的节点和关系类型
kuzu为Rust开发者提供了强大而高效的图数据库功能,适用于各种需要处理复杂关系数据的应用场景。通过合理使用其查询功能,可以构建高性能的图数据应用。
完整示例代码
use kuzu::{Database, Connection};
fn main() {
// 1. 创建数据库和连接
let db = Database::new("social_network_db").unwrap();
let conn = Connection::new(&db).unwrap();
// 2. 定义节点和关系模式
conn.execute("CREATE NODE TABLE User(name STRING, age INT64, PRIMARY KEY (name))").unwrap();
conn.execute("CREATE NODE TABLE Post(title STRING, content STRING, PRIMARY KEY (title))").unwrap();
conn.execute("CREATE REL TABLE Follows(FROM User TO User, since INT64)").unwrap();
conn.execute("CREATE REL TABLE Wrote(FROM User TO Post)").unwrap();
// 3. 插入数据
conn.execute("CREATE (:User {name: 'Alice', age: 30})").unwrap();
conn.execute("CREATE (:User {name: 'Bob', age: 25})").unwrap();
conn.execute("CREATE (:Post {title: 'Rust Guide', content: 'Learning Rust'})").unwrap();
// 建立关系
conn.execute("MATCH (a:User {name: 'Alice'}), (b:User {name: 'Bob'}) CREATE (a)-[:Follows {since: 2020}]->(b)").unwrap();
conn.execute("MATCH (a:User {name: 'Alice'}), (p:Post {title: 'Rust Guide'}) CREATE (a)-[:Wrote]->(p)").unwrap();
// 4. 基本查询
println!("All users:");
let result = conn.execute("MATCH (u:User) RETURN u.name, u.age").unwrap();
for row in result.iter() {
let name: String = row.get(0).unwrap();
let age: i64 = row.get(1).unwrap();
println!("- {} (age: {})", name, age);
}
// 5. 复杂图查询
println!("\nPosts written by Alice's friends:");
let result = conn.execute(
"MATCH (a:User {name: 'Alice'})-[:Follows]->(friend:User)-[:Wrote]->(post:Post)
RETURN friend.name, post.title, post.content"
).unwrap();
for row in result.iter() {
let friend: String = row.get(0).unwrap();
let title: String = row.get(1).unwrap();
let content: String = row.get(2).unwrap();
println!("- {} wrote post '{}': {}", friend, title, content);
}
// 6. 创建索引优化查询性能
conn.execute("CREATE INDEX ON :User(name)").unwrap();
}