主题
ArcadeDB
ArcadeDB 是一个多模型 NoSQL 数据库,支持图、文档、键值、时序与向量数据。它提供了一个内置的 LSM_VECTOR 索引(由 JVector/HNSW 驱动),用于高性能的近似最近邻(ANN)向量搜索。
langchain4j 集成支持两种运行模式:
- 远程模式 —— 通过 HTTP 连接到 ArcadeDB 服务器。适合生产部署与共享基础设施。
- 嵌入模式 —— 在同一 JVM 内以进程内方式运行 ArcadeDB。无需服务器或 Docker 容器;数据库存储在本地文件系统上。非常适合测试、桌面应用或单进程工作负载。
Maven 依赖
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-arcadedb</artifactId>
<version>${latest version here}</version>
</dependency>1
2
3
4
5
2
3
4
5
注意:这是一个社区集成模块。你可能需要在项目配置中添加 langchain4j-community 仓库。
API
ArcadeDBEmbeddingStore
特性
- 两种运行模式:远程(用 HTTP 客户端连接 ArcadeDB 服务器)或嵌入(ArcadeDB 进程内运行,无需服务器)
- 多模型数据库:将嵌入作为顶点存储在 ArcadeDB 的图模型中,与文档、键值与时序数据并存
- HNSW 向量索引:使用 ArcadeDB 的 LSM_VECTOR 索引(基于 JVector)进行快速近似最近邻搜索
- 元数据过滤:支持用比较与逻辑运算符按元数据过滤搜索结果
- 持久化存储:在远程与嵌入两种模式下,数据都能跨重启持久保存
- 自动 schema 创建:首次使用时自动创建顶点类型、属性与向量索引
- 多种相似度函数:支持 COSINE(默认)、EUCLIDEAN 与 SQUARED_EUCLIDEAN 距离度量(远程模式)
- 批量操作:一次调用添加多个嵌入
- 灵活移除:按 ID、按过滤条件移除,或清空全部
基本用法
远程模式
远程模式连接到一个正在运行的 ArcadeDB 服务器。要在本地启动一个,参见用 Docker 运行 ArcadeDB。
连接到已有数据库
java
EmbeddingStore<TextSegment> embeddingStore = ArcadeDBEmbeddingStore.builder()
.host("localhost")
.port(2480)
.databaseName("my_database")
.username("root")
.password("playwithdata")
.dimension(384) // Must match your embedding model's dimension
.build();1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
自动创建数据库
java
EmbeddingStore<TextSegment> embeddingStore = ArcadeDBEmbeddingStore.builder()
.host("localhost")
.port(2480)
.databaseName("my_database")
.username("root")
.password("playwithdata")
.dimension(384)
.createDatabase(true) // Create database if it doesn't exist
.build();1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
嵌入模式
嵌入模式在同一 JVM 内运行 ArcadeDB。无需服务器——只需提供一个本地文件系统上用于存储数据库的路径。若数据库尚不存在,会自动创建。
使用完毕后务必调用 close() 以释放资源。
java
ArcadeDBEmbeddingStore embeddingStore = ArcadeDBEmbeddingStore.embeddedBuilder()
.databasePath("/path/to/my-database")
.dimension(384) // Must match your embedding model's dimension
.build();
// ... use the store ...
embeddingStore.close();1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
使用 try-finally(或通过一个包装器使用 try-with-resources)来确保 close() 总被调用:
java
ArcadeDBEmbeddingStore embeddingStore = ArcadeDBEmbeddingStore.embeddedBuilder()
.databasePath("/path/to/my-database")
.dimension(384)
.build();
try {
// ... use the store ...
} finally {
embeddingStore.close();
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
添加与搜索嵌入
两种模式下的搜索 API 完全相同:
java
// Add a text segment with its embedding
TextSegment segment = TextSegment.from("Hello, world!", Metadata.from("source", "example"));
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);
// Search for similar embeddings
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(5)
.minScore(0.7)
.build();
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(request).matches();1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
配置选项
远程模式
java
EmbeddingStore<TextSegment> embeddingStore = ArcadeDBEmbeddingStore.builder()
.host("localhost") // Required: ArcadeDB server hostname
.port(2480) // Default: 2480 (HTTP port)
.databaseName("my_database") // Required: database name
.username("root") // Required: username
.password("playwithdata") // Required: password
.typeName("EmbeddingDocument") // Default: "EmbeddingDocument" — vertex type name
.dimension(384) // Required: embedding vector dimension
.similarityFunction("COSINE") // Default: "COSINE" — similarity metric
.maxConnections(16) // Default: 16 — HNSW graph connections per node
.beamWidth(100) // Default: 100 — HNSW search beam width
.createDatabase(false) // Default: false — auto-create the database
.metadataPrefix("meta_") // Default: "meta_" — prefix for metadata properties
.build();1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
嵌入模式
java
ArcadeDBEmbeddingStore embeddingStore = ArcadeDBEmbeddingStore.embeddedBuilder()
.databasePath("/path/to/my-database") // Required: local filesystem path for the database
.typeName("EmbeddingDocument") // Default: "EmbeddingDocument" — vertex type name
.dimension(384) // Default: 384 — embedding vector dimension
.maxConnections(16) // Default: 16 — HNSW graph connections per node
.beamWidth(100) // Default: 100 — HNSW search beam width
.metadataPrefix("") // Default: "" (no prefix) — prefix for metadata properties
.build();1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
参数指南
共享参数(两种模式):
- typeName:用于存储嵌入文档的顶点类型。更改它可在同一数据库内实现多个嵌入存储
- dimension:必须与你嵌入模型的输出维度精确相符
- maxConnections:控制 HNSW 索引中的图连通性。更高的值提升召回,但增加内存与索引构建时间。推荐:16–128
- beamWidth:控制 HNSW 索引构建与搜索的质量。更高的值以速度为代价带来更好的召回。推荐:100–500
- metadataPrefix:元数据键作为顶点属性存储时施加的前缀。若你的元数据键与内置属性冲突,请更改它
仅远程参数:
- host:ArcadeDB 服务器的主机名或 IP 地址(必填)
- port:ArcadeDB REST API 的 HTTP 端口(默认:2480)
- databaseName:要连接或创建的数据库(必填)
- username / password:ArcadeDB 凭据(必填)
- similarityFunction:
COSINE—— 余弦相似度;最适合归一化向量(默认)EUCLIDEAN—— 欧氏距离SQUARED_EUCLIDEAN—— 平方欧氏距离;比 EUCLIDEAN 更快
- createDatabase:设为
true可在数据库不存在时自动创建它
仅嵌入参数:
- databasePath:嵌入数据库存储所在目录的路径。若不存在会自动创建
- database:或者,直接提供一个已有的
com.arcadedb.database.Database实例,而非路径
元数据过滤
ArcadeDB 支持按元数据过滤搜索结果。过滤在向量索引查找之后应用。
java
// Filter by a single metadata value
Filter filter = new IsEqualTo("source", "wikipedia");
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(5)
.filter(filter)
.build();
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(request).matches();1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
支持的过滤类型
比较运算符:
IsEqualTo、IsNotEqualToIsGreaterThan、IsGreaterThanOrEqualToIsLessThan、IsLessThanOrEqualToIsIn、IsNotIn
逻辑运算符:
And、Or、Not
移除操作
java
// Remove by list of IDs
embeddingStore.removeAll(List.of("id1", "id2"));
// Remove by metadata filter
embeddingStore.removeAll(new IsEqualTo("source", "old-source"));
// Remove all embeddings
embeddingStore.removeAll();1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
当前限制
- 近似搜索:HNSW 索引是近似的。对于包含大量近乎相同向量的超大结果集,某些文档可能不会被返回
- 内存内过滤:元数据过滤是在向量搜索之后于内存内应用,而非在索引层执行。为抵消过滤造成的缩减,存储会抓取最多 5 倍于所请求数量的结果
- 浮点精度:ArcadeDB 以 JSON double 返回向量,相比原始存储值可能引入轻微的浮点精度差异。
Double.MIN_VALUE(4.9E-324)会下溢为 0.0,无法精确存储 - 无字符串内容过滤:不支持基于字符串的内容过滤(例如
ContainsString);仅提供上文列出的元数据过滤类型 - 嵌入模式无相似度函数选择:嵌入 builder 不暴露
similarityFunction选项;索引使用其默认度量
用 Docker 运行 ArcadeDB
远程模式所需。最快的上手方式:
bash
docker run -d \
--name arcadedb \
-p 2480:2480 \
-e JAVA_OPTS="-Darcadedb.server.rootPassword=playwithdata" \
arcadedata/arcadedb:latest1
2
3
4
5
2
3
4
5
然后连接你的存储:
java
EmbeddingStore<TextSegment> embeddingStore = ArcadeDBEmbeddingStore.builder()
.host("localhost")
.port(2480)
.databaseName("embeddings")
.username("root")
.password("playwithdata")
.dimension(384)
.createDatabase(true)
.build();1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
示例
- 关于集成测试示例,请查看 langchain4j-community-arcadedb 模块中的测试文件
- 你也能在 langchain4j-examples 项目中找到一些示例