MrDoc
MrDoc优化事项
KT企业知识库-重要信息
文档与文集全文检索方案
测试用例
全文搜索-线上测试用例
常见QA
测试用例- Mermaid 支持Emoji表情和中文
本文档使用 MrDoc 发布
-
+
首页
文档与文集全文检索方案
# 文档与文集全文检索方案 ## 1. 前置工作 ### 技术栈 - **依赖栈**:Django + Haystack + Whoosh - **中文分词**:`jieba` 驱动(`ChineseAnalyzer` 内部使用 `jieba.cut(..., cut_all=True)`) ### 索引配置 - **索引定义**:`app_doc/search_indexes.py` 中的 `DocIndex`、`ProjectIndex` - 数据源均限制为 `status=1` 的已发布内容 - **索引模板**: - `template/search/indexes/app_doc/doc_text.txt` 载入文档标题、预览内容、正文 - `Project` 索引模板类似 - **配置文件**:`MrDoc/settings.py` 配置 `HAYSTACK_CONNECTIONS` - 使用自定义 whoosh 引擎 - 启用 `RealtimeSignalProcessor` 以响应 `model.save()` 事件 - **索引存储**:`whoosh_index/` 挂载于宿主机 - 需要读写权限并保持定期备份 - 如索引损坏可执行 `python manage.py rebuild_index --noinput` 重建 --- ## 2. 方案设计 ### 2.1 检索分词规则 - 中文关键字会先经 `jieba` 切词 - 当分词结果包含多个 token 时,QueryParser 默认以 **AND** 组合(需同时包含全部词条) - 若词典仅给出一个 token,则要求文档包含完整短语 ### 2.2 文档搜索 (`/api/get_self_docs/`) **权限集合**:合并「本人创建」+「可浏览/协作」+「公开」文集的 `Doc` **搜索流程**: 1. 调用 `SearchQuerySet().models(Doc)` 获取全文检索命中 ID 2. 使用 ORM 模糊匹配 `name/pre_content/content` 兜底,确保 Whoosh 漏索引时仍可命中 3. 两者取并集后按照 `modify_time` 排序、去重并分页返回 ### 2.3 文集搜索 (`/api/get_projects/`) **权限集合**:根据筛选条件拼出可见文集 ID 列表 **搜索流程**: - 优先使用 Haystack 获取匹配项目 ID - 若为空再回退到 `name/intro` 的 `icontains` 查询 ### 2.4 索引一致性 - 直接调用 `QuerySet.update` 不会触发 `RealtimeSignalProcessor` - 在批量更新场景(如文集转让、移动文档)新增 `refresh_doc_index(doc_ids)` 手动刷新 - 普通编辑改为 `doc.save()`,补发 Haystack 信号并同步写索引 --- ## 3. 方案实现逻辑 ### 3.1 `app_api/views.py:get_self_docs` - 新增权限范围合并、`base_docs` 预筛选及全文检索 + ORM fallback 并集逻辑 - 针对异常记录统一返回空列表,保持排序、分页逻辑不变 ### 3.2 `app_doc/utils.py` - 新增 `refresh_doc_index(doc_ids)` - 通过 `connections['default']` 逐一 `update_object`,作为批量操作补救措施 ### 3.3 `app_doc/views.py` - **`modify_doc`**: - 改用实例 `save()` 写入,保存后调用 `refresh_doc_index` - 避免 `QuerySet.update` 遗漏增量索引 - **批量操作**(文集转让、移动文档含子级等): - 收集受影响文档 ID - 调用 `refresh_doc_index` ### 3.4 其他 - 保留 `get_projects` 原有逻辑 - 仅记录其与文档搜索相同的 fallback 思路,无需改动 --- ## 4. 测试方案 ### 4.1 索引同步测试 修改文档 2 内容,删除、添加关键词后执行: ```bash curl -Gs "http://localhost:10086/api/get_self_docs/" \ --data-urlencode "token=adminapitoken" \ --data-urlencode "kw=Token" ``` **预期**:删除关键词后立即从结果剔除 ### 4.2 短语命中测试 **测试用例 1**:仅文档 3 含"部署步骤"短语 ```bash curl -Gs "http://localhost:10086/api/get_self_docs/" \ --data-urlencode "token=adminapitoken" \ --data-urlencode "kw=部署步骤" ``` **预期**:仅返回 ID 3 **测试用例 2**:文档 2 同时包含"部署""步骤"但非连续时 **预期**:仍命中(因分词结果为两个 token 的 AND 组合) ### 4.3 多词匹配与 fallback 测试 - 在 Whoosh 索引缺失某文档 ID 的情况下 - 验证 `name/__icontains` 等兜底逻辑仍可返回数据 ### 4.4 文集搜索测试 - 使用 `kw=敏感配置` 测试只返回含有完整短语的文集 - 再尝试 `kw="敏感 配置"`(带空格)观察 AND 组合结果 ### 4.5 批量操作索引更新测试 - 执行文集转让或文档移动后,重复全文检索 - 确认相关文档仍可命中 --- ## 5. 故障恢复 如遇索引异常,可运行以下命令重建索引: ```bash python manage.py rebuild_index --noinput ``` 重建后复测以上用例。 ## 6. 注意事项 1、实际调用api需要针对url参数进行url编码,避免因为空格等情况产生错误 2、分词&匹配规则: 关键字:kw=“部署步骤” 分词结果:是两个词条:部署 和 步骤。 匹配规则:然后 Whoosh 的查询解析器会用 AND 逻辑组合这两个词条,所以只有同时含有 “部署” 和 “步骤” 的文档才会命中。
arise
2025年10月6日 17:35
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码