图_2文档入库模块
对应 [[2_代码实现_文档入库]]。将原文解析成三级 Chunk;父块与叶块分别进入不同存储。
主要流程
- 调用
DocumentLoader.load_document()。PDF / Word / Excel 用现有加载器;HTML 先经过正文整理,然后回到统一入口。 - 每页先清洗再递归切出三层。父子 ID 随每一个 Chunk 一起生成,供后续 Auto-Merging 回查父块。
- 由调用方分离 L1/L2 和 L3:先调用
ParentChunkStore.upsert_documents(),再调用MilvusWriter.write_documents()。本章测试中的test_full_indexing_pipeline展示了这一编排;不要额外理解成源码里已有一个入库 Pipeline 类。 - Writer 使用共享的
EmbeddingService计算 Dense 向量,交给MilvusStore插入。BM25 由 Milvus 集合内的 Function 计算。
阅读重点
重点是 DocumentLoader 的统一返回结构、三级父子关系和 Writer 的输入边界。HTML 细节只在网页分支执行,不是所有文档都先转 HTML。图中没有纳入第 8 篇之后的上传接口和任务调度。
图形约定
绿色是目录,蓝色是文件,紫色是类,橙色是函数;标题中的名称与职责之间保留 12 个空格。类框中的编号通常对应其方法;函数框的编号描述内部步骤。没有组合,矩形宽高可分别调整。
导航
[[项目实现|查看项目实现总图]] · [[图_1数据存储模块|数据存储模块]]
Excalidraw Data
Text Elements
backend/ 承载本模块的后端代码 ^3f4c58b6
indexing/ 解析文档、分块并写入索引 ^568d8a0e
[[2_代码实现_文档入库#2.1 document_loader.py|document_loader.py]] 统一格式入口与三级分块 ^271417b7
sanitize_text() 去除不可用字符
- 清理 NUL、控制字符、零宽字符,保留换行等排版字符 ^2bf1d1b5
DocumentLoader 把原文转成统一 Chunk 列表
- init():建立 L1 / L2 / L3 三个递归分块器
- load_documents_from_folder():遍历支持的文件,逐个加载
- load_document():分派 PDF / Word / Excel / HTML 加载器
- _load_from_langchain_docs():清洗正文、补齐来源,逐页分块
- _split_page_to_three_levels():页内 L1 → L2 → L3 逐级切分
- _build_chunk_id():文件名 :: 页码 :: 层级 :: 层内序号 ^416e1b73
[[2_代码实现_文档入库#2.2 html_processor.py|html_processor.py]] 把html文档分页 ^4f881777
load_html_for_document_loader() 接入统一加载流程
- 调用 parse_html_file_to_sections() 获取章节
- 将章节包装为 LangChain Document,附带标题 / 页码元数据 ^a6acb2fe
parse_html_file_to_sections() 提取并切分网页正文
- _read_html_text():识别 BOM / charset,尝试 UTF-8 / GB18030
- _strip_noise() / _pick_root():去脚本导航,选择正文
- _doc_title():提取页面标题;_br_to_newlines():保留换行
- _linearize_blocks():把标题、段落、列表、表格转为有序文本
- _split_into_sections():按二级标题组织章节 ^a91ff540
HTML 分支 ^ad5902a8
[[2_代码实现_文档入库#2.3 embedding.py|embedding.py]] 统一入库与查询使用的密集向量模型 ^b545ab69
_create_dense_embedder() 读取配置并建立本地模型
- HuggingFaceEmbeddings;默认 BAAI/bge-m3、CPU
- normalize_embeddings=True;不在 Python 侧计算 BM25 稀疏向量 ^4c167e4a
EmbeddingService 提供共享的文本向量化接口
- init():持有一个本地 Dense 模型
- get_embeddings(texts):批量编码;空输入返回 [],失败抛异常 ^69eabc17
embedding_service = EmbeddingService():进程内共享实例。 查询端复用它,避免索引与查询使用不同的向量空间。 ^cfa4b20d
[[2_代码实现_文档入库#2.4 milvus_writer.py|milvus_writer.py]] 批量编码并写入 L3 叶块 ^d7e93f23
MilvusWriter 把调用方传入的 Chunk 写入向量库
- init():复用 embedding_service 和 MilvusStore
- write_documents():初始化集合;默认每批 50 条
- 提取 text → get_embeddings() → 组装全文 / 向量 / 关联 ID
- 调用 MilvusStore.insert(),成功后累计条数并回调进度
- 调用方只传 L3;本类不保存 L1 / L2,不负责文件上传 ^3923fc88
存储依赖见 [[图_1数据存储模块]]: L1 / L2 → ParentChunkStore → PostgreSQL + Redis L3 → MilvusStore → Milvus(BM25 由集合内置 Function 生成) ^18967c94
get_embeddings(texts) ^e43b2a6a
Element Links
271417b7: [[2_代码实现_文档入库#2.1 document_loader.py]]
4f881777: [[2_代码实现_文档入库#2.2 html_processor.py]]
b545ab69: [[2_代码实现_文档入库#2.3 embedding.py]]
d7e93f23: [[2_代码实现_文档入库#2.4 milvus_writer.py]]
18967c94: [[图_1数据存储模块]]
%%
Drawing
1 | N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATLZMzYBXUtiRoIACyhQ4zZAHoFAc0JRJQgEYA6bGwC2CgF7N6hbEcK4OCtptbErHALRY8RMpWdx8Q1TdIEfARcZgRmBShcZQUebR4ATm0ARho6IIR9BA4oZm4AbXAwUDBSiBJuCAAWADMEAHZ6gA4eGrTSyFhESsDsKI5lYPayzG4qgFZ+MphuZKqABinIChJ1 |
%%