Rust图数据库插件库kuzu的使用,kuzu提供高效图数据存储与查询功能

Rust图数据库插件库kuzu的使用,kuzu提供高效图数据存储与查询功能

Kuzu Logo

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);
    }
}

这个示例展示了如何:

  1. 创建或打开一个kuzu数据库
  2. 创建节点表和关系表
  3. 插入节点和关系数据
  4. 执行查询并处理结果

高级特性

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(())
}

这个完整示例展示了:

  1. 数据库初始化和连接创建
  2. 创建节点表和关系表
  3. 插入节点和关系数据
  4. 简单查询和复杂查询
  5. 事务处理
  6. 参数化查询

所有操作都包含错误处理,使用了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();

性能优化建议

  1. 为常用查询属性创建索引:
conn.execute("CREATE INDEX ON :User(name)").unwrap();
  1. 对于大型图,考虑分批处理查询结果

  2. 使用参数化查询避免重复解析查询语句

  3. 合理设计图模式,避免过度复杂的节点和关系类型

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();
}
回到顶部