4.5 KiB
4.5 KiB
元数据管线 — 开发规格
2026-07-19
1. 需求概述
系统在启动和运行时,需要自动完成三个任务:
| # | 任务 | 说明 |
|---|---|---|
| 1 | 新相册解析 | 扫描磁盘导入的新相册 → 提取人名+标签 → 写入 DB |
| 2 | 老数据重解析 | 已有数据的相册用最新逻辑重新提取,强制覆盖 |
| 3 | 人物合并 | 按中文核心合并同一人的不同记录 |
这三件事通过同一个管道完成,管道在启动时跑一次 + 定时每 30 分钟跑一次。
2. 启动流程(时序)
当前问题:import 和 pipeline 是两个并发的 tokio::spawn,pipeline 固定等 3s,import 可能耗时更长,导致刚导入的相册没被解析。
目标时序:
服务启动
│
├── DB 初始化
│
├─── 后台任务 A:启动管线(单次)─────┐
│ ├── ① 扫描导入新相册 │
│ ├── ② Phase 1:全量解析(强制覆盖) │
│ ├── ③ Phase 2:人物合并 │
│ └── ④ 刷新内存缓存 │
│ │
├─── 后台任务 B:定时管线(每 30 分钟)──┤
│ ├── ① Phase 1:全量解析(强制覆盖) │
│ ├── ② Phase 2:人物合并 │
│ └── ③ 刷新内存缓存 │
│ │
└─── HTTP 服务启动 │
│
注:后台任务 A 和 B 互斥,不会同时执行
变化要点
- 启动管线 = import + parse + merge + refreshCache 依次串行
- 定时管线 = parse + merge + refreshCache(不重复 import)
- 管线内部顺序固定不可并发
3. 管线内部结构
run_pipeline(db, with_import: bool)
│
├── [with_import=true] 扫描导入新相册
│
├── Phase 1:全量解析
│ for each album:
│ ├── jieba 分词 → 候选人名 + 候选标签
│ ├── 人物库匹配 / jieba → 最佳人名
│ ├── 强制写入 albums.person_name_* + persons + aliases
│ ├── 标签三步提取(词库→jieba→正则)
│ ├── unique_tags(去重+排序+坏标签过滤)
│ └── 强制写入 albums.tags + album_tags
│
├── Phase 2:人物合并
│ ├── 提取所有人名的中文核心
│ ├── 分组 → 每组选最多相册的为目标
│ └── 合并相册关联 / 别名,删除源
│
└── Phase 3:刷新缓存
└── 重新加载 albums 到 AlbumsCache
4. 模块职责
| 模块 | 文件 | 职责 |
|---|---|---|
| Pipeline 引擎 | engine/pipeline.rs |
phase_parse_all()、phase_merge_persons()、run_pipeline() |
| 标题解析 | engine/title_parser.rs |
jieba 分词、人名提取、中英文拆分、别名生成 |
| 标签提取 | engine/tag_extractor.rs |
分类词库匹配、jieba 名词提取、标点/停用词/坏标签过滤 |
| 人物合并 | engine/person_merger.rs |
中文核心提取、分组分析、合并执行 |
| 导入 | services/import.rs |
扫描磁盘目录、创建相册和图片记录 |
| DB | db/metadata.rs |
persons、aliases、album_tags 表的读写 |
| 缓存 | cache/mod.rs |
AlbumsCache + TagCache + PersonCache |
5. 关键设计约束
- 强制覆盖:每次管线执行都是完整重解,直接覆盖 DB 数据
- 幂等:管线可反复执行,不影响正确性
- 串行:管线内部各阶段顺序执行,不并发
- 多级过滤:标签经过 5 层过滤才入库,确保质量
- 中文优先:人名优先中文,中英混杂拆为"主名+别名"
- 纯中/纯英:人名主体不允许中英混杂
6. 实现清单
6.1 Pipeline 引擎
phase_parse_all()— 全量解析phase_merge_persons()— 人物合并phase_refresh_cache()— 刷新缓存(在 main.rs 实现)run_pipeline(db)— 整合解析+合并
6.2 main.rs 启动逻辑
- 后台任务 A:顺序执行 import → run_pipeline → cache refresh
- 后台任务 B:定时每 30 分钟 run_pipeline → cache refresh
6.3 API
- POST /api/pipeline/run → 全量解析 + 人物合并