Skip to content
LangChain4j 文档版本 1.22.0 源快照 ebfd3f24 更新于 2026-10-14

OceanBase

OceanBase 嵌入存储与 OceanBase 数据库集成,提供向量相似度搜索与混合搜索能力。

Maven 依赖

xml
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-oceanbase</artifactId>
    <version>${latest version here}</version>
</dependency>

注意:这是一个社区集成模块。你可能需要在项目配置中添加 langchain4j-community 仓库。

API

  • OceanBaseEmbeddingStore

要求

  • OceanBase 数据库实例(4.3.5 或更新版本)
  • Java >= 17

特性

  • 存储带元数据(JSON 格式)的嵌入
  • 使用 cosine、L2 或内积距离的向量相似度搜索
  • 混合搜索:结合向量相似度与全文搜索(RRF 算法)
  • 按元数据字段与表列过滤搜索结果
  • 自动创建表与向量索引
  • 可自定义字段名与距离度量

用量

基本示例

java
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.allminilml6v2q.AllMiniLmL6V2QuantizedEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingSearchResult;
import dev.langchain4j.store.embedding.oceanbase.OceanBaseEmbeddingStore;

// Initialize embedding model
EmbeddingModel embeddingModel = new AllMiniLmL6V2QuantizedEmbeddingModel();

// Create embedding store
OceanBaseEmbeddingStore embeddingStore = OceanBaseEmbeddingStore.builder()
    .url("jdbc:oceanbase://127.0.0.1:2881/test")
    .user("root@test")
    .password("password")
    .tableName("embeddings")
    .dimension(384)
    .build();

// Add document with metadata
String id = embeddingStore.add(
    embeddingModel.embed("Java is a programming language").content(),
    TextSegment.from("Java is a programming language", 
        Metadata.from("category", "programming").put("language", "Java"))
);

// Search
Embedding queryEmbedding = embeddingModel.embed("programming language").content();
EmbeddingSearchResult<TextSegment> results = embeddingStore.search(
    EmbeddingSearchRequest.builder()
        .queryEmbedding(queryEmbedding)
        .maxResults(10)
        .build()
);

// Process results
results.matches().forEach(match -> {
    System.out.println("Score: " + match.score());
    System.out.println("Text: " + match.embedded().text());
    System.out.println("Metadata: " + match.embedded().metadata());
});

高级配置

java
OceanBaseEmbeddingStore embeddingStore = OceanBaseEmbeddingStore.builder()
    .url("jdbc:oceanbase://127.0.0.1:2881/test")
    .user("root@test")
    .password("password")
    .tableName("embeddings")
    .dimension(384)
    .metricType("cosine")  // Options: "cosine", "l2", "ip"
    .retrieveEmbeddingsOnSearch(true)
    .idFieldName("id_field")
    .textFieldName("text_field")
    .metadataFieldName("metadata_field")
    .vectorFieldName("vector_field")
    .build();

距离度量

OceanBase 嵌入存储支持三种距离度量。距离值会被自动转换为 [0, 1] 区间内的相关性分数,其中 1 表示最相关的匹配。

余弦距离(默认)- "cosine"

最适合: 文本嵌入、语义相似度搜索

工作原理:

  • OceanBase cosine_distance 返回值范围在 [0, 2]
    • 0 = 相同向量(方向一致)
    • 1 = 正交向量(互相垂直)
    • 2 = 相反向量(方向完全相反)
  • 转换为相关性分数:score = (2 - distance) / 2
  • 结果与向量的模长无关
java
.metricType("cosine")  // Default, recommended for text embeddings

L2 距离(欧氏)- "l2" 或 "euclidean"

最适合: 当方向与模长都很重要时

工作原理:

  • 衡量向量之间的直线距离
  • 范围:[0, ∞)
  • 转换为相关性分数:score = 1 / (1 + distance)
java
.metricType("l2")  // or "euclidean"

内积 - "inner_product" 或 "ip"

最适合: 归一化嵌入、性能至关重要的应用

工作原理:

  • 衡量向量的点积
  • 对归一化向量而言,范围是 [-1, 1]
  • 转换为相关性分数:score = (inner_product + 1) / 2
java
.metricType("inner_product")  // or "ip"

参考: OceanBase 向量距离函数

过滤

OceanBase 嵌入存储支持按元数据字段与表列过滤搜索结果。

按元数据字段过滤

java
import dev.langchain4j.store.embedding.filter.MetadataFilterBuilder;
import static dev.langchain4j.store.embedding.filter.MetadataFilterBuilder.metadataKey;

// Filter by single metadata field
Filter filter = metadataKey("category").isEqualTo("programming");

// Filter with multiple conditions
Filter filter = new And(
    metadataKey("category").isEqualTo("programming"),
    metadataKey("language").isEqualTo("Java")
);

// Filter with IN operator
Filter filter = metadataKey("language").isIn("Java", "Python", "C++");

// Search with filter
EmbeddingSearchResult<TextSegment> results = embeddingStore.search(
    EmbeddingSearchRequest.builder()
        .queryEmbedding(queryEmbedding)
        .filter(filter)
        .maxResults(10)
        .build()
);

按表列过滤

你也可以直接按表列过滤(id、text、metadata、vector):

java
import dev.langchain4j.store.embedding.filter.comparison.IsIn;
import dev.langchain4j.store.embedding.filter.comparison.ContainsString;
import dev.langchain4j.store.embedding.filter.comparison.IsEqualTo;

// Filter by ID field
Filter filter = new IsIn("id", List.of("id1", "id2", "id3"));

// Filter by text field (contains)
Filter textFilter = new ContainsString("text", "programming");

// Filter by exact text match
Filter exactTextFilter = new IsEqualTo("text", "Java programming");

注:按表列过滤时,请使用你在 FieldDefinition 中定义的实际字段名。映射器会自动识别常用别名:

  • id → id 字段
  • text 或 document → text 字段
  • metadata → metadata 字段
  • vector 或 embedding → vector 字段

支持的过滤操作

  • isEqualTo:相等比较
  • isNotEqualTo:不相等比较
  • isGreaterThan:大于比较
  • isGreaterThanOrEqualTo:大于等于比较
  • isLessThan:小于比较
  • isLessThanOrEqualTo:小于等于比较
  • isIn:IN 运算(多值)
  • isNotIn:NOT IN 运算
  • containsString:LIKE 运算(模式匹配)
  • And:逻辑与
  • Or:逻辑或
  • Not:逻辑非

混合搜索

混合搜索结合向量相似度搜索与全文搜索,以提供更好的搜索结果。启用后,它会在 text 字段上自动创建一个全文索引,并用 倒数排名融合(RRF) 算法合并结果。

启用混合搜索

java
OceanBaseEmbeddingStore embeddingStore = OceanBaseEmbeddingStore.builder()
    .url("jdbc:oceanbase://127.0.0.1:2881/test")
    .user("root@test")
    .password("password")
    .tableName("embeddings")
    .dimension(384)
    .enableHybridSearch(true)  // Enable hybrid search
    .build();

执行混合搜索

java
// Perform hybrid search by providing both query embedding and query text
EmbeddingSearchResult<TextSegment> results = embeddingStore.search(
    EmbeddingSearchRequest.builder()
        .queryEmbedding(queryEmbedding)  // Vector embedding for similarity search
        .query("search text")            // Text query for fulltext search
        .maxResults(10)
        .build()
);

混合搜索的工作原理

  1. 向量搜索:使用查询嵌入执行相似度搜索
  2. 全文搜索:在 text 字段上使用 MATCH AGAINST 执行全文搜索
  3. 结果融合:用 RRF(倒数排名融合)算法合并结果
    • 公式:score = Σ(1 / (k + rank)),其中 k=60
    • 来自两种搜索的每个结果都依据其排名对最终分数作出贡献
    • 结果被归一化并按组合后的 RRF 分数排序

优势:

  • 更好的召回:既能按语义相似度、也能按精确关键词找到文档
  • 更高的精度:RRF 有效地平衡了两种搜索
  • 比单独的向量搜索更好地处理精确关键词匹配

实现细节

分数计算

该嵌入存储直接在 SQL 查询中计算相关性分数:

  • Cosine:score = (2 - cosine_distance) / 2
  • L2/欧氏:score = 1 / (1 + distance)
  • 内积:score = (inner_product + 1) / 2

分数在 [0, 1] 区间内返回,其中 1 表示最相关的匹配。

元数据处理

  • 元数据以 JSON 形式存储在数据库中
  • 较大的 Long 值(> 2^53-1)会被自动序列化为字符串以保留精度
  • 过滤同时支持直接的列过滤与 JSON 元数据过滤

表结构

默认情况下,嵌入表会有以下列:

名称类型描述
idVARCHAR(36)主键。用于存储 UUID 字符串,这些字符串在嵌入存储时生成
vectorJSON以 JSON 数组存储嵌入向量
textTEXT存储文本片段
metadataJSON以 JSON 存储元数据

限制

  • removeAll(Filter) 与 removeAll() 方法尚不支持。请改用 removeAll(Collection<String> ids)。
  • 按表列过滤时,字段名不区分大小写,但必须与实际列名或可识别的别名相符。

参考

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。