PGVector
LangChain4j 与 PGVector 无缝集成,使开发者能够将 向量嵌入直接存储在 PostgreSQL 中并查询。该集成非常适合语义搜索、 RAG 等应用场景。
Maven 依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pgvector</artifactId>
<version>1.18.1-beta28</version>
</dependency>
Gradle 依赖
implementation 'dev.langchain4j:langchain4j-pgvector:1.18.1-beta28'
API
PgVectorEmbeddingStore
参数摘要
| 纯 Java 属性 | 说明 | 默认值 | 必需/可选 |
|---|---|---|---|
datasource | 用于数据库连接的 DataSource 对象。仅在 PgVectorEmbeddingStore.datasourceBuilder() 构建器变体中可用。若未提供,则必须在 PgVectorEmbeddingStore.builder() 构建器变体中分别提供 host、port、user、password 和 database。 | 无 | 若未分别提供 host、port、user、password 和 database,则为必需。 |
host | PostgreSQL 服务器主机名。未提供 DataSource 时必需。 | 无 | 未提供 DataSource 时必需 |
port | PostgreSQL 服务器端口号。未提供 DataSource 时必需。 | 无 | 未提供 DataSource 时必需 |
user | 数据库认证用户名。未提供 DataSource 时必需。 | 无 | 未提供 DataSource 时必需 |
password | 数据库认证密码。未提供 DataSource 时必需。 | 无 | 未提供 DataSource 时必需 |
database | 要连接的数据库名称。未提供 DataSource 时必需。 | 无 | 未提供 DataSource 时必需 |
table | 用于存储嵌入的数据库表名。 | 无 | 必需 |
dimension | 嵌入向量的维度。应与所用嵌入模型匹配。可使用 embeddingModel.dimension() 动态设置。 | 无 | 必需 |
useIndex | IVFFlat 索引将向量划分为多个列表,然后搜索与查询向量最接近的子集列表。与 HNSW 相比,构建更快、内存占用更少,但查询性能(速度-召回权衡)较低。应使用 IVFFlat 索引。 | false | 可选 |
indexListSize | IVFFlat 索引的列表数量。 | 无 | 何时必需:若 useIndex 为 true,则必须提供 indexListSize 且必须大于零。否则程序在表初始化期间会抛出异常。何时可选:若 useIndex 为 false,则忽略该属性,无需设置。 |
createTable | 是否自动创建嵌入表。 | true | 可选 |
dropTableFirst | 是否在重新创建表之前先删除表(对测试很有用)。 | false | 可选 |
searchMode | 使用的搜索模式。选项:
| VECTOR | 可选 |
rrfK | RRF(Reciprocal Rank Fusion)算法中使用的常数 k:Score = 1/(k + rank_vector) + 1/(k + rank_keyword)。较低的值(20-40)更强调顶部结果;较高的值(80-100)产生更均衡的排名。仅在 searchMode 设为 HYBRID 时相关。 | 60 | 可选。仅在 HYBRID 搜索模式下使用。 |
textSearchConfig | 关键词搜索使用的 PostgreSQL 文本搜索配置名称(例如 simple、english、german)。仅在 searchMode 为 HYBRID 时适用。 | simple | 可选。仅在 HYBRID 搜索模式下使用。 |
metadataStorageConfig | 处理与嵌入关联的元数据的配置对象。支持三种存储模式:
| COMBINED_JSON | 可选。若未设置,则使用带有 COMBINED_JSON 的默认配置。 |
示例
为演示 PGVector 的能力,可以使用 Docker 化的 PostgreSQL 环境。它借助 Testcontainers 运行带有 PGVector 的 PostgreSQL。
使用 Docker 快速开始
要快速搭建带有 PGVector 扩展的 PostgreSQL 实例,可以使用以下 Docker 命令:
docker run --rm --name langchain4j-postgres-test-container -p 5432:5432 -e POSTGRES_USER=my_user -e POSTGRES_PASSWORD=my_password pgvector/pgvector
命令说明:
docker run:运行新容器。--rm:容器停止后自动删除,确保不留残留数据。--name langchain4j-postgres-test-container:将容器命名为 langchain4j-postgres-test-container,便于 识别。-p 5432:5432:将本地机器的 5432 端口映射到容器的 5432 端口。-e POSTGRES_USER=my_user:将 PostgreSQL 用户名设为 my_user。-e POSTGRES_PASSWORD=my_password:将 PostgreSQL 密码设为 my_password。pgvector/pgvector:指定要使用的 Docker 镜像,已预配置 PGVector 扩展。
以下是两个创建 PgVectorEmbeddingStore 的代码示例。第一个仅使用必需参数,
第二个配置了所有可用参数。
- 仅必需参数
EmbeddingStore<TextSegment> embeddingStore = PgVectorEmbeddingStore.builder()
.host("localhost") // Required: Host of the PostgreSQL instance
.port(5432) // Required: Port of the PostgreSQL instance
.database("postgres") // Required: Database name
.user("my_user") // Required: Database user
.password("my_password") // Required: Database password
.table("my_embeddings") // Required: Table name to store embeddings
.dimension(embeddingModel.dimension()) // Required: Dimension of embeddings
.build();
- 设置全部参数
在这个变体中,我们包含了所有常用的可选参数,如 useIndex、indexListSize、 createTable、dropTableFirst 和 metadataStorageConfig。请根据需要调整这些值:
EmbeddingStore<TextSegment> embeddingStore = PgVectorEmbeddingStore.builder()
// Required parameters
.host("localhost")
.port(5432)
.database("postgres")
.user("my_user")
.password("my_password")
.table("my_embeddings")
.dimension(embeddingModel.dimension())
// Optional parameters
.useIndex(true) // Enable IVFFlat index
.indexListSize(100) // Number of lists for IVFFlat index
.createTable(true) // Automatically create the table if it doesn’t exist
.dropTableFirst(false) // Don’t drop the table first (set to true if you want a fresh start)
.metadataStorageConfig(MetadataStorageConfig.combinedJsonb()) // Store metadata as a combined JSONB column
.build();
如果只想用最小配置快速上手,请使用第一个示例。 第二个示例展示了如何利用所有可用的 builder 参数,以获得更多控制和自定义能力。
使用 PGVector 的完整 RAG 示例
本节演示如何使用带有 PGVector 扩展的 PostgreSQL 构建完整的检索增强生成(RAG)系统,用于语义搜索。
概述
RAG 系统包含两个主要阶段:
- 索引阶段(离线):加载文档、切分为块、生成嵌入,并存储到 pgvector
- 检索阶段(在线):对用户查询做嵌入、搜索相似块、将上下文注入 LLM 提示
前置条件
确保已运行带有 PGVector 的 PostgreSQL 实例(参见上文的 Docker 设置)。
1. 文档摄入(索引阶段)
此示例展示如何加载文档、切分为块,并将嵌入存储到 pgvector:
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.DocumentParser;
import dev.langchain4j.data.document.DocumentSplitter;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import static dev.langchain4j.data.document.loader.FileSystemDocumentLoader.loadDocument;
// Load document (PDF, TXT, etc.)
Document document = loadDocument("/path/to/document.pdf", new ApachePdfBoxDocumentParser());
// Split document into smaller chunks
// 300 tokens per chunk, 50 tokens overlap for context continuity
DocumentSplitter splitter = DocumentSplitters.recursive(300, 50);
// Create embedding model (384 dimensions for AllMiniLmL6V2)
EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
// Create pgvector embedding store
EmbeddingStore<TextSegment> embeddingStore = PgVectorEmbeddingStore.builder()
.host("localhost")
.port(5432)
.database("postgres")
.user("my_user")
.password("my_password")
.table("document_embeddings")
.dimension(embeddingModel.dimension()) // 384 for AllMiniLmL6V2
.build();
// Ingest: split document, generate embeddings, and store in pgvector
EmbeddingStoreIngestor.builder()
.documentSplitter(splitter)
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build()
.ingest(document);
System.out.println("Document ingested successfully!");