ETL 数据管道
ETL(Extract, Transform, Load)是 RAG 应用的数据处理基础。它的作用是把原始文档转换成向量数据库能用的格式,确保数据以最优方式存储,方便后续检索。
简单说,ETL 管道负责:读取文档 → 转换处理 → 存储到向量库。
ETL 的核心组件
Spring AI 的 ETL 管道由三个核心接口组成:
DocumentReader(文档读取器)
负责从各种数据源读取文档,转换成 Document 对象。
public interface DocumentReader extends Supplier<List<Document>> {
default List<Document> read() {
return get();
}
}
DocumentTransformer(文档转换器)
对文档进行转换处理,比如分块、清洗、增强等。
public interface DocumentTransformer extends Function<List<Document>, List<Document>> {
default List<Document> transform(List<Document> documents) {
return apply(documents);
}
}
DocumentWriter(文档写入器)
把处理好的文档写入目标存储,比如向量数据库、文件等。
public interface DocumentWriter extends Consumer<List<Document>> {
default void write(List<Document> documents) {
accept(documents);
}
}
基本使用
最简单的 ETL 流程就是把这三个组件链起来:
// 假设我们有这三个组件
PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(resource);
TokenTextSplitter textSplitter = new TokenTextSplitter(1000, 200);
VectorStore vectorStore = ...;
// 方式一:函数式风格
vectorStore.accept(textSplitter.apply(pdfReader.get()));
// 方式二:更直观的方法名
vectorStore.write(textSplitter.split(pdfReader.read()));
流程就是:读取 PDF → 文本分块 → 写入向量库。
Document 类
Document 是 ETL 管道的核心数据结构,包含:
- 文本内容:文档的主要内容
- 元数据:文档的附加信息(来源、页码、时间等)
- 媒体内容:可选的图片、音频、视频
Document doc = new Document("这是文档内容");
doc.getMetadata().put("source", "product-manual.pdf");
doc.getMetadata().put("page", 1);
DocumentReader 实现
Spring AI 提供了多种文档读取器,支持不同的数据源。
PDF 文档
PagePdfDocumentReader
按页读取 PDF 文档,每页生成一个 Document。
@Component
public class PdfDocumentService {
public List<Document> loadPdf(Resource pdfResource) {
PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(pdfResource);
return pdfReader.get();
}
}
TikaPdfDocumentReader
基于 Apache Tika 的 PDF 读取器,功能更强大。
@Component
public class TikaPdfService {
public List<Document> loadPdfWithTika(Resource pdfResource) {
TikaPdfDocumentReader reader = new TikaPdfDocumentReader(pdfResource);
return reader.get();
}
}
文本文件
TextReader
读取纯文本文件。
@Component
public class TextDocumentService {
public List<Document> loadText(Resource textResource) {
TextReader textReader = new TextReader(textResource);
return textReader.get();
}
}
JSON 文档
JsonReader
从 JSON 文件中提取内容,可以指定哪些字段作为文档内容。
@Component
public class JsonDocumentService {
private final Resource jsonResource;
public JsonDocumentService(@Value("classpath:bikes.json") Resource jsonResource) {
this.jsonResource = jsonResource;
}
public List<Document> loadJson() {
// 使用 "description" 和 "content" 字段作为文档内容
JsonReader jsonReader = new JsonReader(
this.jsonResource,
"description",
"content"
);
return jsonReader.get();
}
}
构造函数选项:
JsonReader(Resource resource)- 使用所有字段JsonReader(Resource resource, String... jsonKeysToUse)- 指定字段JsonReader(Resource resource, JsonMetadataGenerator generator, String... jsonKeysToUse)- 自定义元数据生成
网页内容
WebPdfDocumentReader
从 URL 读取 PDF 文档。
@Component
public class WebDocumentService {
public List<Document> loadWebPdf(String url) {
WebPdfDocumentReader reader = new WebPdfDocumentReader(url);
return reader.get();
}
}
其他格式
Spring AI 还支持:
- Markdown:
MarkdownReader - Word 文档:
TikaDocumentReader(通过 Tika) - Excel:
TikaDocumentReader - PowerPoint:
TikaDocumentReader