moduforge-search 0.7.0

moduforge 搜索服务 - SQLite 后端
Documentation
# ModuForge Search - SQLite 搜索引擎


基于 SQLite + FTS5 的高性能树形文档搜索引擎。

## ✨ 特性


- **全文搜索** - SQLite FTS5 虚拟表,支持中文分词
-**树形查询** - 原生 `WITH RECURSIVE` 递归查询
-**结构化查询** - 完整 SQL 支持,灵活组合条件
-**增量更新** - 事务级增量索引更新
-**高并发** - WAL 模式,读写分离
-**零配置** - 内嵌 SQLite,无需额外依赖

## 🚀 快速开始


### 基本使用


```rust
use mf_search::{SqliteBackend, SearchService, SearchQuery};
use std::sync::Arc;

#[tokio::main]

async fn main() -> anyhow::Result<()> {
    // 1. 创建后端
    let backend = Arc::new(SqliteBackend::new_in_dir("./data/index")?);
    let service = SearchService::new(backend);

    // 2. 全文搜索
    let results = service.search_text("富文本编辑器", 10).await?;
    println!("找到 {} 条结果", results.len());

    // 3. 树形查询(递归)
    let results = service.query_descendants("root", 100).await?;
    println!("子树节点数: {}", results.len());

    // 4. 按类型查询
    let results = service.query_by_type("paragraph", 20).await?;
    println!("段落数: {}", results.len());

    Ok(())
}
```

### 复杂查询


```rust
let results = service.search(SearchQuery {
    text: Some("搜索关键词".to_string()),
    node_type: Some("section".to_string()),
    parent_id: Some("parent_id".to_string()),
    marks: vec!["bold".to_string(), "important".to_string()],
    attrs: vec![("status".to_string(), "published".to_string())],
    sort_by: Some("created_at_i64".to_string()),
    sort_asc: false,
    limit: 20,
    ..Default::default()
}).await?;
```

### 与 State 集成


```rust
use mf_search::create_search_index_plugin;
use mf_state::{State, StateConfig};

let search_plugin = create_search_index_plugin("./data/index")?;

let state = State::create(StateConfig {
    schema: Some(schema),
    plugins: Some(vec![search_plugin]),
    ..Default::default()
}).await?;

// 自动索引更新
let mut tr = state.tr();
tr.add_node("root".into(), vec![node])?;
let result = state.apply(tr).await?; // 索引自动同步
```

## 📊 查询类型


### 1. 全文搜索


```rust
// FTS5 全文索引
SearchQuery {
    text: Some("富文本编辑器".to_string()),
    limit: 50,
    ..Default::default()
}
```

### 2. 树形递归


```rust
// 获取节点及所有子孙节点
SearchQuery {
    parent_id: Some("root".to_string()),
    include_descendants: true,
    limit: 1000,
    ..Default::default()
}
```

### 3. 精确过滤


```rust
SearchQuery {
    node_type: Some("paragraph".to_string()),
    parent_id: Some("section_1".to_string()),
    marks: vec!["bold".to_string()],
    ..Default::default()
}
```

### 4. 属性查询


```rust
// JSON 属性查询
SearchQuery {
    attrs: vec![
        ("status".to_string(), "published".to_string()),
        ("priority".to_string(), "high".to_string()),
    ],
    ..Default::default()
}
```

### 5. 范围查询


```rust
SearchQuery {
    range_field: Some("created_at_i64".to_string()),
    range_min: Some(1000000),
    range_max: Some(2000000),
    ..Default::default()
}
```

### 6. 路径前缀


```rust
// 查询路径以 "/root/section" 开头的所有节点
SearchQuery {
    path_prefix: Some("/root/section".to_string()),
    ..Default::default()
}
```

## 🏗️ 架构


```
┌─────────────────────────────────────────┐
│          SearchService                  │  ← 高层查询接口
│  (search_text, query_descendants, ...)  │
└──────────────────┬──────────────────────┘
┌──────────────────▼──────────────────────┐
│         SqliteBackend                   │  ← SQLite 后端
│  ┌─────────────────────────────────┐   │
│  │  nodes (主表)                    │   │
│  │  - 结构化数据                     │   │
│  │  - B-tree 索引                    │   │
│  └─────────────────────────────────┘   │
│  ┌─────────────────────────────────┐   │
│  │  nodes_fts (FTS5)                │   │
│  │  - 全文索引                       │   │
│  │  - 触发器自动同步                 │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘
```

## 🎯 性能特点


| 操作 | 性能 | 说明 |
|------|------|------|
| 全文搜索 | ~5-10ms | FTS5 倒排索引 |
| 树形递归 | ~3ms | WITH RECURSIVE |
| 精确过滤 | ~2ms | B-tree 索引 |
| 批量插入 | ~50K/s | WAL 模式 |
| 索引大小 | 1.2x | 原始数据的 1.2 倍 |

## 🔧 配置选项


### 创建选项


```rust
// 1. 指定目录
SqliteBackend::new_in_dir("./data/index")?

// 2. 系统临时目录
SqliteBackend::new_in_system_temp()?

// 3. 自定义临时根目录
SqliteBackend::new_in_temp_root("/tmp/myapp")?
```

### 查询选项


```rust
pub struct SearchQuery {
    pub text: Option<String>,           // 全文搜索
    pub node_type: Option<String>,      // 节点类型
    pub parent_id: Option<String>,      // 父节点
    pub path_prefix: Option<String>,    // 路径前缀
    pub marks: Vec<String>,             // 标记列表
    pub attrs: Vec<(String, String)>,   // 属性键值对
    pub limit: usize,                   // 返回数量(默认 50)
    pub offset: usize,                  // 偏移量
    pub sort_by: Option<String>,        // 排序字段
    pub sort_asc: bool,                 // 排序方向
    pub include_descendants: bool,      // 包含子树
    pub range_field: Option<String>,    // 范围查询字段
    pub range_min: Option<i64>,         // 最小值
    pub range_max: Option<i64>,         // 最大值
}
```

## 🧪 测试


```bash
# 运行测试

cargo test -p moduforge-search

# 运行示例

cargo run --example basic -p moduforge-search

# 基准测试

cargo bench -p moduforge-search
```

## 📝 迁移指南


从 Tantivy 迁移到 SQLite:

1. **更新依赖** - 已自动完成
2. **更新代码** - `TantivyBackend``SqliteBackend`
3. **更新插件** - `create_tantivy_index_plugin``create_search_index_plugin`
4. **查询 API 兼容** - `SearchQuery` 保持不变

## 🎁 优势对比


| 特性 | Tantivy | SQLite | 说明 |
|------|---------|--------|------|
| 全文搜索 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | SQLite FTS5 足够强大 |
| 树形查询 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 原生 WITH RECURSIVE |
| SQL 查询 || ⭐⭐⭐⭐⭐ | 完整 SQL 支持 |
| 事务 | ⭐⭐ | ⭐⭐⭐⭐⭐ | ACID 保证 |
| 维护成本 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 熟悉的 SQL |
| 写入性能 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | WAL 高并发 |

## 📚 参考


- [SQLite FTS5]https://www.sqlite.org/fts5.html
- [Recursive CTE]https://www.sqlite.org/lang_with.html
- [rusqlite]https://docs.rs/rusqlite/