MySQL 驱动直连,JdbcClient 直接用:向量混合搜索,一个库全搞定 OceanBase 团队最近开源了 seekdb 。
一句话:它是 AI 原生的混合搜索数据库。在一个库里同时搞定关系型存储(MySQL 100% 兼容)、向量检索(HNSW 索引)、全文搜索、JSON 半结构化数据。
一条 SQL,完成”向量搜索 + 全文匹配 + 结构化过滤”的联合查询。不用写胶水代码拼接技术栈,直接驱动 RAG 流程。
seekdb vs 其他向量数据库 看看 seekdb 和主流方案的对比:
功能
seekdb
Chroma
Milvus
PostgreSQL
嵌入式数据库
✅
✅
✅
❌
MySQL 兼容
✅
❌
❌
❌
向量搜索
✅
✅
✅
插件
全文搜索
✅
❌
部分支持
插件
混合搜索
✅
❌
✅
部分支持
OLTP
✅
❌
❌
✅
OLAP
✅
❌
❌
✅
开源协议
Apache 2.0
Apache 2.0
Apache 2.0
PostgreSQL License
我觉得它最大的几个卖点:
特性
说明
MySQL 兼容
零学习成本,现有客户端直接连
轻量部署
单节点轻量,Docker 就能跑
混合搜索
向量+全文+结构化,一条 SQL 语句搞定
支持嵌入应用
以轻量级库的形式嵌入您的应用
一行命令跑起来
部署有多简单?
1 docker run -d --name seekdb -p 2881:2881 oceanbase/seekdb:latest
完事。用 MySQL 客户端连 localhost:2881 就行。
Python 用户想要嵌入式方式,pip 一装:
Spring Boot 3 + JdbcClient 实战 看代码。
我用 Spring Boot 3.5 + JdbcClient 对接 seekdb,演示三个场景:建表、向量插入、混合搜索。
1. 依赖配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-jdbc</artifactId > </dependency > <dependency > <groupId > com.mysql</groupId > <artifactId > mysql-connector-j</artifactId > </dependency > <dependency > <groupId > dev.langchain4j</groupId > <artifactId > langchain4j-open-ai</artifactId > <version > 1.0.0-beta3</version > </dependency > </dependencies >
2. 数据库连接 1 2 3 4 5 6 spring: datasource: url: jdbc:mysql://localhost:2881/test?useSSL=false username: root@test password: driver-class-name: com.mysql.cj.jdbc.Driver
seekdb 用的是 MySQL 协议,JDBC URL 和驱动都用 MySQL 的。
3. 建表语句 1 2 3 4 5 6 7 8 9 10 11 12 13 CREATE TABLE documents ( id BIGINT AUTO_INCREMENT PRIMARY KEY , title VARCHAR (512 ) NOT NULL , content TEXT, vector VECTOR(1536 ), metadata JSON, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE VECTOR INDEX vec_idx ON documents(vector) WITH (DISTANCE= COSINE, TYPE= HNSW);
VECTOR(1536) 是 seekdb 的向量类型。建索引用 CREATE VECTOR INDEX,语法很直观。
4. 插入向量数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Service @RequiredArgsConstructor public class DocumentService { private final JdbcClient jdbcClient; private final EmbeddingModel embeddingModel; public Long insertDocument (String title, String content, String metadata) { float [] vector = embeddingModel.embed(title + " " + content) .content().vector(); String vectorJson = toJsonArray(vector); return jdbcClient.sql(""" INSERT INTO documents (title, content, vector, metadata) VALUES (?, ?, ?, ?) """ ) .params(title, content, vectorJson, metadata) .update(); } private String toJsonArray (float [] vector) { return "[" + Arrays.stream(vector) .mapToObj(String::valueOf) .collect(Collectors.joining("," )) + "]" ; } }
向量用 JSON 数组格式传进去,seekdb 自动解析。
5. 向量语义搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public List<SearchResult> semanticSearch (String query, int topK) { float [] queryVector = embeddingModel.embed(query).content().vector(); String vectorJson = toJsonArray(queryVector); return jdbcClient.sql(""" SELECT id, title, content, Cosine_distance(vector, ?) AS distance FROM documents ORDER BY Cosine_distance(vector, ?) APPROXIMATE LIMIT ? """ ) .params(vectorJson, vectorJson, topK) .query(SearchResult.class) .list(); }
Cosine_distance() 计算余弦距离,值越小越相似。加 APPROXIMATE 走索引,不加就全表扫描(精确但慢)。
6. 混合搜索 这是 seekdb 的杀手锏。向量语义 + 关键词全文匹配,效果比单一方式好得多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public List<HybridSearchResult> hybridSearch ( String query, int topK, double keywordWeight, // 关键词权重,建议 0.3 double semanticWeight) { float [] queryVector = embeddingModel.embed(query).content().vector(); String vectorJson = toJsonArray(queryVector); String likePattern = "%" + query + "%" ; return jdbcClient.sql(""" SELECT id, title, content, -- 关键词命中得 1 分 CASE WHEN title LIKE ? OR content LIKE ? THEN 1.0 ELSE 0.0 END AS keyword_score, -- 语义相似度(距离转相似度) (1 - Cosine_distance(vector, ?)) AS semantic_score, -- 加权综合得分 (CASE WHEN title LIKE ? OR content LIKE ? THEN 1.0 ELSE 0.0 END) * ? + (1 - Cosine_distance(vector, ?)) * ? AS final_score FROM documents ORDER BY final_score DESC LIMIT ? """ ) .params(likePattern, likePattern, vectorJson, likePattern, likePattern, keywordWeight, vectorJson, semanticWeight, topK) .query(HybridSearchResult.class) .list(); }
Spring AI Alibaba 快速集成
注意 :这里只能支持向量相似度搜索,没有实现混合搜索的能力。如果需要混合搜索(语义+关键词),还是得自己写 SQL。
依赖 1 2 3 4 5 6 7 8 9 <dependency > <groupId > com.alibaba.cloud.ai</groupId > <artifactId > spring-ai-alibaba-starter</artifactId > </dependency > <dependency > <groupId > com.alibaba.cloud.ai</groupId > <artifactId > spring-ai-alibaba-starter-store-oceanbase</artifactId > <version > 1.0.0.2</version > </dependency >
配置 1 2 3 4 5 6 7 8 9 10 11 12 13 spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} vectorstore: oceanbase: enabled: true url: jdbc:oceanbase://localhost:2881/test username: password: tableName: ai_documents defaultTopK: 5 defaultSimilarityThreshold: 0.7
使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @RestController @RequiredArgsConstructor public class RagController { private final OceanBaseVectorStore vectorStore; @PostMapping("/documents") public String addDocuments () { List<Document> docs = List.of( new Document ("Spring Boot 3.5 发布了" , Map.of("type" , "news" )), new Document ("seekdb 支持混合搜索" , Map.of("type" , "tech" )) ); vectorStore.add(docs); return "OK" ; } @GetMapping("/search") public List<Document> search (@RequestParam String query) { return vectorStore.similaritySearch( SearchRequest.builder().query(query).topK(5 ).build() ); } }
Spring AI 的抽象层帮你搞定 Embedding 生成、向量存储、相似度检索。代码量砍半。
写在最后 AI 应用开发正在从”拼凑式架构”走向”一体化架构”。seekdb 代表的 AI 原生数据库思路,本质是把向量能力下沉到数据库层,而不是在应用层做集成。
对 Java 开发者来说,MySQL 兼容意味着几乎零学习成本。JdbcTemplate、JdbcClient、MyBatis 都能直接用。再配合 Spring AI Alibaba 的 VectorStore 抽象,RAG 应用的数据层开发体验提升了一个档次。
如果你正在做 AI 相关的项目,试试 seekdb。