问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

使用Docker安装和操作Qdrant向量数据库

创作时间:
作者:
@小白创作中心

使用Docker安装和操作Qdrant向量数据库

引用
CSDN
1.
https://m.blog.csdn.net/weimeilayer/article/details/144353837

Qdrant是一个开源的向量数据库,支持大规模的向量存储和相似度搜索。本文将介绍如何使用Docker快速安装Qdrant,并通过Java客户端进行基本操作。

使用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的编程语言。

Java客户端操作Qdrant

添加Maven依赖

<dependency>
    <groupId>io.qdrant</groupId>
    <artifactId>client</artifactId>
    <version>3.7.0</version>
</dependency>

创建集合并插入向量

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' 创建成功,并已插入向量。");
    }
}

查询集合中的向量(基于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删除集合中的指定点。
  • 更新点的向量:更新某个点的向量值,适用于数据的修改。

每个案例展示了不同的操作,你可以根据具体需求进行调整。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号