使用Docker安装Qdrant向量数据库
使用Docker安装Qdrant向量数据库命令。数据不存储到宿主机外部
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
要在 Docker 中运行 Qdrant 并将数据存储到宿主机,可以使用以下命令:
docker run -p 6333:6333 -p 6334:6334 \
-v /data/qdrant/storage:/qdrant/storage \
qdrant/qdrant
参数说明:
-p 6333:6333 和 -p 6334:6334:将容器的 6333 和 6334 端口映射到宿主机。
-v /data/qdrant/data:/qdrant/storage:
/data/qdrant/data 是宿主机上的目录,用于存储 Qdrant 的数据。
/qdrant/storage 是容器内部的存储路径
注意事项:
请确保 /data/qdrant/data 目录在宿主机上存在,并具有 Docker 容器可以写入的权限。如果目录不存在,可以通过以下命令创建:
mkdir -p /data/qdrant/data
chmod 777 /data/qdrant/data
如果 Qdrant 更新或容器被销毁,数据会保存在宿主机上,不会丢失。
完成后,您可以通过访问 http://<宿主机IP>:6333 来访问 Qdrant 服务。
Qdrant架构
上图展示了 Qdrant 一些主要组件的高级概述。以下是您应该熟悉的术语。
集合(Collections):集合是一组命名的点(带有有效负载的向量),您可以在其中进行搜索。同一集合中每个点的向量必须具有相同的维度,并通过单个度量进行比较。命名向量可用于在单个点中包含多个向量,每个向量都可以有自己的维度和度量要求。
距离度量(Distance Metrics):这些用于测量向量之间的相似性,必须在创建集合的同时选择它们。度量的选择取决于向量的获取方式,特别是取决于将用于编码新查询的神经网络。
点(Points):点是 Qdrant 运行的中心实体,它们由向量和可选的 id 和有效负载组成。
id:向量的唯一标识符。
矢量(Vector):数据的高维表示,例如图像、声音、文档、视频等。
有效负载(Payload):有效负载是一个 JSON 对象,其中包含可以添加到向量中的附加数据。
存储(Storage):Qdrant 可以使用两种存储选项之一:内存存储(将所有向量存储在 RAM 中,具有最高速度,因为仅需要持久性才需要磁盘访问)或Memmap存储(创建与磁盘上的文件)。
客户端:可用于连接到 Qdrant 的编程语言。
client.search()参数说明:
collection_name(必需):要搜索的集合名称。
query_vector(必需):查询向量。可以是以下类型之一:
types.NumpyArray:NumPy 数组表示的向量。
Sequence[float]:浮点数列表表示的向量。
Tuple[str, List[float]]:带有向量名称的元组。
types.NamedVector:命名向量对象。
query_filter(可选):过滤器条件。可以使用 types.Filter 类型的对象来指定过滤条件。默认为 None。
search_params(可选):搜索参数。可以使用 types.SearchParams 类型的对象来指定搜索参数。默认为 None。
ef(可选):查询的有效范围(Efficient Search)。它控制搜索的速度和准确性之间的权衡。较高的值会提高搜索准确性,但会增加搜索时间。
ef_search(可选):查询期间的最大搜索次数。它控制搜索的时间和资源消耗。较高的值会增加搜索时间,但可能提高搜索结果的准确性。
limit(可选):返回结果的最大数量。默认为 10。
offset(可选):结果偏移量,用于分页。默认为 0。
with_payload(可选):是否返回结果的负载信息。
True:返回搜索结果中的所有载荷数据。
False:不返回任何载荷数据。
Sequence[str]:指定要返回的特定载荷字段列表。
with_vectors(可选):是否返回结果的向量信息。
score_threshold(可选):结果的得分阈值。只返回得分高于或等于阈值的结果。默认为 None,表示不应用阈值。
append_payload(可选):是否将负载信息追加到搜索结果中。默认为 True。
consistency(可选):读一致性选项。可以是 types.ReadConsistency 类型的对象,用于指定读操作的一致性级别。默认为 None。
**kwargs:其他可选参数。
search方法返回一个包含 types.ScoredPoint 对象的列表,每个对象表示一个得分较高的向量点。
添加Maven依赖
<dependency>
<groupId>io.qdrant</groupId>
<artifactId>client</artifactId>
<version>1.12.0</version>
</dependency>
4.Java操作Qdrant
官方文档:Local Quickstart - Qdrant
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.collections.Collections;
import io.qdrant.client.grpc.models.VectorParams;
import io.qdrant.client.grpc.models.Vector;
import io.qdrant.client.grpc.models.Point;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class QdrantExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端,指定服务器地址和端口
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 创建一个名为 "dev_collection" 的集合,指定向量的大小和距离度量方式
client.createCollectionAsync("dev_collection",
Collections.VectorParams.newBuilder()
.setDistance(Collections.Distance.Cosine) // 设置距离度量为 Cosine 相似度
.setSize(4) // 设置向量的大小为 4
.build()).get(); // 等待创建完成
// 定义要插入的向量(每个向量包含 4 个浮动值)
List<Vector> vectors = List.of(
Vector.newBuilder().addValues(0.1f, 0.2f, 0.3f, 0.4f).build(), // 向量 1
Vector.newBuilder().addValues(0.5f, 0.6f, 0.7f, 0.8f).build() // 向量 2
);
// 创建要插入的点(每个点包含唯一的 ID 和相应的向量)
List<Point> points = List.of(
Point.newBuilder().setId(1).setVector(vectors.get(0)).build(), // 点 1
Point.newBuilder().setId(2).setVector(vectors.get(1)).build() // 点 2
);
// 将定义的点(向量)插入到 "dev_collection" 集合中
client.upsertAsync("dev_collection", points).get(); // 异步插入并等待完成
// 输出成功信息
System.out.println("集合 'dev_collection' 创建成功,并已插入向量。");
}
}
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.collections.Collections;
import io.qdrant.client.grpc.models.VectorParams;
import io.qdrant.client.grpc.models.Vector;
import io.qdrant.client.grpc.models.Point;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class QdrantExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端,指定服务器地址和端口
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder(“172.16.17.111”, 6334, false).build());
// 创建一个名为 "dev_collection" 的集合,指定向量的大小和距离度量方式
client.createCollectionAsync("dev_collection",
Collections.VectorParams.newBuilder()
.setDistance(Collections.Distance.Cosine) // 设置距离度量为 Cosine 相似度
.setSize(4) // 设置向量的大小为 4
.build()).get(); // 等待创建完成
// 定义要插入的向量(每个向量包含 4 个浮动值)
List<Vector> vectors = List.of(
Vector.newBuilder().addValues(0.1f, 0.2f, 0.3f, 0.4f).build(), // 向量 1
Vector.newBuilder().addValues(0.5f, 0.6f, 0.7f, 0.8f).build() // 向量 2
);
// 创建要插入的点(每个点包含唯一的 ID 和相应的向量)
List<Point> points = List.of(
Point.newBuilder().setId(1).setVector(vectors.get(0)).build(), // 点 1
Point.newBuilder().setId(2).setVector(vectors.get(1)).build() // 点 2
);
// 将定义的点(向量)插入到 "dev_collection" 集合中
client.upsertAsync("dev_collection", points).get(); // 异步插入并等待完成
// 输出成功信息
System.out.println("集合 'dev_collection' 创建成功,并已插入向量。");
}
}
创建 Qdrant 客户端:通过提供 Qdrant 服务器的 IP 地址和端口号来创建客户端。
创建集合:创建名为 dev_collection 的集合,并指定向量的大小为 4,采用 Cosine 相似度计算向量间的距离。
插入向量:定义两个向量,每个向量包含 4 个浮动值,并将它们插入到集合中,每个向量与唯一的 ID 关联。
输出信息:插入完成后,打印信息确认操作成功。
确保你的项目中包含 Qdrant Java 客户端库,以便代码能够正常运行。
- 创建集合并插入多个向量、
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.collections.Collections;
import io.qdrant.client.grpc.models.Vector;
import io.qdrant.client.grpc.models.Point;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class QdrantInsertMultipleVectors {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端,连接到 Qdrant 服务
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 创建集合 "my_collection",向量大小为 4,使用余弦相似度
client.createCollectionAsync("my_collection",
Collections.VectorParams.newBuilder()
.setDistance(Collections.Distance.Cosine)
.setSize(4)
.build()).get();
// 定义多个向量
List<Vector> vectors = List.of(
Vector.newBuilder().addValues(0.1f, 0.2f, 0.3f, 0.4f).build(),
Vector.newBuilder().addValues(0.5f, 0.6f, 0.7f, 0.8f).build(),
Vector.newBuilder().addValues(0.9f, 0.8f, 0.7f, 0.6f).build()
);
// 创建点(每个点包含一个 ID 和对应的向量)
List<Point> points = List.of(
Point.newBuilder().setId(1).setVector(vectors.get(0)).build(),
Point.newBuilder().setId(2).setVector(vectors.get(1)).build(),
Point.newBuilder().setId(3).setVector(vectors.get(2)).build()
);
// 插入向量数据
client.upsertAsync("my_collection", points).get();
System.out.println("多个向量已成功插入到 'my_collection' 集合中。");
}
}
- 查询集合中的向量(基于 ID 查询)
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.models.Point;
import java.util.concurrent.ExecutionException;
public class QdrantQueryById {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 查询集合 "my_collection" 中 ID 为 1 的点
Point point = client.retrievePointAsync("my_collection", 1).get();
// 输出查询结果
System.out.println("查询到的点:ID = " + point.getId() + ", 向量 = " + point.getVector().getValuesList());
}
}
- 根据向量进行最近邻搜索
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.models.Vector;
import io.qdrant.client.grpc.models.SearchResult;
import io.qdrant.client.grpc.models.VectorParams;
import io.qdrant.client.grpc.models.SearchRequest;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class QdrantSearchNearestNeighbors {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 定义查询向量
Vector queryVector = Vector.newBuilder().addValues(0.2f, 0.3f, 0.4f, 0.5f).build();
// 构建搜索请求,进行最近邻搜索
SearchRequest searchRequest = SearchRequest.newBuilder()
.setCollectionName("my_collection")
.setQueryVector(queryVector)
.setTop(3) // 返回最相似的前 3 个向量
.setParams(VectorParams.newBuilder().setDistance(VectorParams.Distance.Cosine).build())
.build();
// 执行搜索
List<SearchResult> searchResults = client.searchAsync(searchRequest).get();
// 输出搜索结果
System.out.println("最近邻搜索结果:");
for (SearchResult result : searchResults) {
System.out.println("ID = " + result.getId() + ", 距离 = " + result.getScore());
}
}
}
- 删除集合中的点
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import java.util.concurrent.ExecutionException;
public class QdrantDeletePoint {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 删除集合 "my_collection" 中 ID 为 2 的点
client.deletePointAsync("my_collection", 2).get();
System.out.println("点 ID 为 2 的数据已从集合中删除。");
}
}
- 更新集合中的向量
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.QdrantGrpcClient;
import io.qdrant.client.grpc.models.Vector;
import io.qdrant.client.grpc.models.Point;
import java.util.concurrent.ExecutionException;
public class QdrantUpdateVector {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建 Qdrant 客户端
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("172.16.17.111", 6334, false).build());
// 定义更新后的向量
Vector updatedVector = Vector.newBuilder().addValues(0.8f, 0.7f, 0.6f, 0.5f).build();
// 创建点并更新向量
Point updatedPoint = Point.newBuilder().setId(1).setVector(updatedVector).build();
// 更新点的向量数据
client.upsertAsync("my_collection", List.of(updatedPoint)).get();
System.out.println("点 ID 为 1 的向量已更新。");
}
}
主要操作:
插入多个向量:在集合中插入多个向量,通常用于批量插入数据。
基于 ID 查询点:通过点的 ID 来查询对应的向量数据。
最近邻搜索:根据一个查询向量进行最近邻搜索,返回最相似的向量。
删除点:通过 ID 删除集合中的指定点。
更新点的向量:更新某个点的向量值,适用于数据的修改。
每个案例展示了不同的操作,你可以根据具体需求进行调整。