137 lines
4.0 KiB
Markdown
137 lines
4.0 KiB
Markdown
# OpenSearch 重建索引脚本
|
||
|
||
## 脚本路径
|
||
|
||
```text
|
||
scripts/reindex_opensearch.php
|
||
```
|
||
|
||
## 脚本作用
|
||
|
||
根据 PostgreSQL 中已经完成向量化的 chunk,重新构建 OpenSearch 中的 `proofdb_chunks` 索引内容,并刷新每条 chunk 的派生搜索字段。
|
||
|
||
脚本会做这些事:
|
||
|
||
1. 确保 OpenSearch 索引存在。
|
||
2. 判断当前是“断点续跑”还是“全量重建”。
|
||
3. 按 archive 选取待处理数据,并按 OpenSearch bulk batch 调用现有 indexing handler。
|
||
4. 批量写入 chunk 文档。
|
||
5. 输出基于 chunk 数的进度条、batch 明细和最终统计结果。
|
||
|
||
## 断点续跑语义
|
||
|
||
默认模式下,脚本会尽量**保留已经完成的 `indexed` 进度**:
|
||
|
||
- 如果 OpenSearch 索引还在,就只把 `queued / indexing / failed_retryable` 的 chunk 重新置回 `pending`,然后继续处理。
|
||
- 如果 OpenSearch 索引已经不存在,脚本会自动切换到全量重建模式,把所有已向量化 chunk 重新置回 `pending`。
|
||
|
||
这意味着如果中途断电、断网、进程被杀:
|
||
|
||
- 已经标记为 `indexed` 的 chunk 进度不会丢。
|
||
- 未完成的那部分在下次重跑脚本时会继续。
|
||
|
||
如果你明确想从头开始全部重建,可以手动加 `--reset`。
|
||
|
||
更具体地说:
|
||
|
||
- 如果 PostgreSQL 里该 chunk 已经是 `indexed`,默认 `resume` 不会重写它,即使 OpenSearch 里同 `_id` 文档已经存在。
|
||
- `--reset` 会把目标范围内所有已向量化 chunk 的 `search_index_status` 统一重置为 `pending`,然后重新 upsert 到 OpenSearch。
|
||
|
||
## 运行前提
|
||
|
||
- PostgreSQL 可连接。
|
||
- OpenSearch 可连接。
|
||
- 目标 chunk 的 `embedding_status` 已经是 `embedded`。
|
||
- 项目依赖已安装完成。
|
||
- 从项目根目录执行命令。
|
||
|
||
如果本地 OpenSearch 使用 HTTPS 且证书是自签名:
|
||
|
||
```bash
|
||
OPENSEARCH_SSL_VERIFY=false php scripts/reindex_opensearch.php
|
||
```
|
||
|
||
## 运行命令
|
||
|
||
全量重建:
|
||
|
||
```bash
|
||
php scripts/reindex_opensearch.php
|
||
```
|
||
|
||
强制从头全量重建:
|
||
|
||
```bash
|
||
php scripts/reindex_opensearch.php --reset
|
||
```
|
||
|
||
只重建一个 archive:
|
||
|
||
```bash
|
||
php scripts/reindex_opensearch.php --archive_uid=01KQHVREB6XPYF604RVZAP9NNY
|
||
```
|
||
|
||
## 成功输出示例
|
||
|
||
```text
|
||
Progress granularity: OpenSearch bulk batches (up to 500 chunks each)
|
||
Reindexing [================================] 100.0% (14/14)
|
||
Batch #1 archive=01KQHVREB6XPYF604RVZAP9NNY chunks=14 progress=14/14
|
||
OpenSearch reindex completed.
|
||
Index: proofdb_chunks
|
||
Archive filter: (all embedded archives)
|
||
Mode: resume
|
||
Eligible embedded chunks: 14
|
||
OpenSearch bulk size: 500
|
||
Reset chunks: 3
|
||
Indexed archives: 1
|
||
Processed batches: 1
|
||
Indexed chunk rows now marked indexed: 14
|
||
Archives: 01KQHVREB6XPYF604RVZAP9NNY
|
||
```
|
||
|
||
## 关于进度条为什么可能“0 到 100”
|
||
|
||
这个脚本的进度条是按 **chunk 数** 计算的,但刷新粒度是 **一次 OpenSearch bulk batch 完成后**。
|
||
|
||
所以如果:
|
||
|
||
- 当前只有一个 archive 需要处理
|
||
- 且该 archive 的待处理 chunk 数小于等于 `opensearch.bulk.chunk_size`
|
||
|
||
那么终端上就会像是从 `0` 直接跳到 `100`。这不是脚本没工作,而是因为这次实际只跑了 `1` 个 bulk batch。
|
||
|
||
## 适用场景
|
||
|
||
- `proofdb_chunks` 被误删后恢复。
|
||
- 数据库里 `search_index_status=3`,但 OpenSearch 中没有对应文档。
|
||
- 索引 mapping 重建后,需要把已经 embedding 完成的数据重新灌回 OpenSearch。
|
||
- archive 的 `summary`、`title`、`tags` 等搜索元数据有更新后,需要刷新到 OpenSearch。
|
||
|
||
## 重要限制
|
||
|
||
这个脚本只处理已经向量化完成的 chunk。
|
||
|
||
它不会:
|
||
|
||
- 重新生成 embedding。
|
||
- 修复 embedding 失败的数据。
|
||
- 修复 PostgreSQL 中缺失的 archive 或 chunk。
|
||
|
||
## 推荐用法
|
||
|
||
如果 OpenSearch 整个索引丢了,通常按下面顺序执行:
|
||
|
||
```bash
|
||
php scripts/setup_opensearch.php
|
||
php scripts/reindex_opensearch.php
|
||
```
|
||
|
||
如果数据库 schema 也有变动,则先补数据库:
|
||
|
||
```bash
|
||
php scripts/setup_database.php
|
||
php scripts/setup_opensearch.php
|
||
php scripts/reindex_opensearch.php
|
||
```
|