最佳体验请使用Chrome67及以上版本、火狐、Edge、Safari浏览器 ×

创建银行
创建开票

    Qdrant向量数据库及基本操作

    编者:杨博@勾股弦数据 阅读78 来源: 知乎 2024/09/18 01:26:49 文章 外链 公开

    Qdrant 使用 Rust 编写,即使在高负载下也能快速、可靠地工作。

    1. Qdrant架构


    上图展示了 Qdrant 一些主要组件的高级概述。以下是您应该熟悉的术语。

    • 集合(Collections):集合是一组命名的点(带有有效负载的向量),您可以在其中进行搜索。同一集合中每个点的向量必须具有相同的维度,并通过单个度量进行比较。命名向量可用于在单个点中包含多个向量,每个向量都可以有自己的维度和度量要求。

    • 距离度量(Distance Metrics):这些用于测量向量之间的相似性,必须在创建集合的同时选择它们。度量的选择取决于向量的获取方式,特别是取决于将用于编码新查询的神经网络。

    • 点(Points):点是 Qdrant 运行的中心实体,它们由向量和可选的 id 和有效负载组成。

    id:向量的唯一标识符。
    矢量(Vector):数据的高维表示,例如图像、声音、文档、视频等。
    有效负载(Payload):有效负载是一个 JSON 对象,其中包含可以添加到向量中的附加数据。
    • 存储(Storage):Qdrant 可以使用两种存储选项之一:内存存储(将所有向量存储在 RAM 中,具有最高速度,因为仅需要持久性才需要磁盘访问)或Memmap存储(创建与磁盘上的文件)。

    • 客户端:可用于连接到 Qdrant 的编程语言。

    2. Google Colab / 本地 Jupyter Lab

    对于想要在 Colab 建立 Qdrant 数据库,方式只有两种:

    • memory,最简单

    • on disk,本文重点探讨的模式

    ## Client
    from qdrant_client import QdrantClient
    
    ## 内存模式,和 FAISS、Chroma等类似
    #client = QdrantClient(":memory:")
    
    ## 本地硬盘模式,本文重点关注。path 这里传入的是一个文件夹
    client=QdrantClient(path="/content/local_qdrant") #基于本地硬盘,进行增删查改。也适用于 Colab+Google Drive

    3. 本地Docker + Jupyter Lab

    本模式适用于开发模式,提供最完整的功能。按照官方说明安装并启动 docker 即可。

    3.1 快速启动

    docker run --privileged -p 6333:6333 qdrant/qdrant

    --privileged 是我本地执行时出现Operation not permitted进程创建受限加的,一般不用加

    3.2 数据挂载启动

    docker run -p 6333:6333 -p 6334:6334 \

    -v $(pwd)/qdrant_storage:/qdrant/storage:z \

    qdrant/qdrant

    在默认配置下,所有数据都将存储在该./qdrant_storage目录中。

    3.3 访问接口

    Qdrant 现在可以访问:

    • REST API:本地主机:6333

    • 网页用户界面:本地主机:6333/dashboard

    • GRPC API:本地主机:6334

    网页直接访问API:http://127.0.0.1:6333/collections,就可以看到collections返回当前的所有集合,那就让我们来用python客户端连接.

    4. 数据操作:增删改查

    4.1 创建一个集合

    from qdrant_client.http.models import Distance, VectorParams
     client.create_collection(
        collection_name="test_collection",
        vectors_config=VectorParams(size=4, distance=Distance.DOT),
    )

    size:向量的大小(维度)

    distance:距离度量类型

    COSINE 余弦相似度(Cosine similarity):余弦相似度是一种常用的向量相似度度量方法,它衡量了两个向量之间的夹角余弦值。在Qdrant中,可以使用COSINE作为距离度量方法来计算余弦相似度。

    点积(Dot Product):它是一种常见的向量运算。点积是将两个向量的对应元素相乘,并将乘积相加得到的标量值。可以使用点积来计算向量之间的夹角余弦值。夹角余弦值反映了两个向量的方向相似程度。夹角余弦值的取值范围在 -1 到 1 之间。

    4.2 添加向量

    现在让我们添加一些带有有效负载的向量。有效负载是您想要与向量关联的其他数据:

    from qdrant_client.http.models import PointStruct
     operation_info = client.upsert(
        collection_name="test_collection",
        wait=True,
        points=[
            PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
            PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
            PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
            PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": "New York"}),
            PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"city": "Beijing"}),
            PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44], payload={"city": "Mumbai"}),
        ],
    )
     
    print(operation_info)

    执行结果:

    operation_id=0 status=<UpdateStatus.COMPLETED: 'completed'>

    4.3 运行查询

    让我们问一个基本问题 - 我们存储的哪个向量与查询向量最相似[0.2, 0.1, 0.9, 0.7]?

    search_result = client.search(
        collection_name="test_collection", query_vector=[0.2, 0.1, 0.9, 0.7], limit=3
        # , with_vectors=True, with_payload=True
    )
     
    print(search_result)

    执行结果:

    ScoredPoint(id=4, version=0, score=1.362, payload={"city": "New York"}, vector=None),
    ScoredPoint(id=1, version=0, score=1.273, payload={"city": "Berlin"}, vector=None),
    ScoredPoint(id=3, version=0, score=1.208, payload={"city": "Moscow"}, vector=None)

    结果以相似度递减的顺序返回。请注意,默认情况下,这些结果中缺少有效负载和矢量数据。有关如何启用它的信息,请参阅结果中的有效负载和向量。

    4.4 添加过滤器

    我们可以通过按有效负载过滤来进一步缩小结果范围。让我们查找包含“London”的最接近的结果。

    from qdrant_client.http.models import Filter, FieldCondition, MatchValue
     search_result = client.search(
        collection_name="test_collection",
        query_vector=[0.2, 0.1, 0.9, 0.7],
        query_filter=Filter(
            must=[FieldCondition(key="city", match=MatchValue(value="London"))]
        ),
        with_payload=True,
        limit=3,
    )
     
    print(search_result)

    执行结果:

    ScoredPoint(id=2, version=0, score=0.871, payload={"city": "London"}, vector=None)

    向量加载到数据库中并使用您自己的向量查询数据库。Qdrant 找到最接近的结果并向您提供相似度分数。

    client.search()参数说明:

    collection_name(必需):要搜索的集合名称。

    query_vector(必需):查询向量。可以是以下类型之一:

    types.NumpyArray:NumPy 数组表示的向量。

    types.NamedVector:命名向量对象。

    query_filter(可选):过滤器条件。可以使用 types.Filter 类型的对象来指定过滤条件。默认为 None。

    search_params(可选):搜索参数。可以使用 types.SearchParams 类型的对象来指定搜索参数。默认为 None。

    ef(可选):查询的有效范围(Efficient Search)。它控制搜索的速度和准确性之间的权衡。较高的值会提高搜索准确性,但会增加搜索时间。

    ef_search(可选):查询期间的最大搜索次数。它控制搜索的时间和资源消耗。较高的值会增加搜索时间,但可能提高搜索结果的准确性。

    with_payload(可选):是否返回结果的负载信息。

    True:返回搜索结果中的所有载荷数据。

    False:不返回任何载荷数据。

    Sequence[str]:指定要返回的特定载荷字段列表。

    with_vectors(可选):是否返回结果的向量信息。

    score_threshold(可选):结果的得分阈值。只返回得分高于或等于阈值的结果。默认为 None,表示不应用阈值。

    consistency(可选):读一致性选项。可以是 types.ReadConsistency 类型的对象,用于指定读操作的一致性级别。默认为 None。

    **kwargs:其他可选参数。

    search方法返回一个包含 types.ScoredPoint 对象的列表,每个对象表示一个得分较高的向量点。

    我们可以根据需要使用这些参数来执行 Qdrant 的搜索操作,并根据返回结果进行进一步处理。

    4.5 删除向量

    def test_delete(self):
        self.client.delete(
            collection_name="test_collection",
            points_selector=models.PointIdsList(
                points=[6],
            ),
        )

    删除指定过滤器下的向量

    def test_delete_filter(self):
        self.client.delete(
            collection_name="test_collection",
            points_selector=models.FilterSelector(
                filter=models.Filter(
                    must=[
                        models.FieldCondition(
                            key="city",
                            match=models.MatchValue(value="New York"),
                        ),
                    ],
                )
            ),
        )

    下面的代码段结合基于MISTRAL向量化模型的向量数据库操作示例代码:

    ## 创建 points
    from mistralai.client import MistralClient
    from qdrant_client import QdrantClient
    from qdrant_client.http.models import PointStruct, VectorParams, Distance
    collection_name = "example_collection"
    
    MISTRAL_API_KEY = "your_mistral_api_key"
    search_client = QdrantClient(":memory:")
    mistral_client = MistralClient(api_key=MISTRAL_API_KEY)
    texts = [
        "Qdrant is the best vector search engine!",
        "Loved by Enterprises and everyone building for low latency, high performance, and scale.", ]
    result = mistral_client.embeddings(
        model="mistral-embed",
        input=texts,)
    points = [
        PointStruct(
            id=idx,
            vector=response.embedding,
            payload={"text": text},
        )
        for idx, (response, text) in enumerate(zip(result.data, texts))]
    
    
    ## 新建一个 collection
    search_client.create_collection(collection_name, vectors_config=
        VectorParams(
            size=1024,
            distance=Distance.COSINE,
        )
    )
    
    ## 在该 collection 插入 points
    search_client.upsert(collection_name, points)



    声明:本网站部分内容来源于网络,版权归原权利人所有,其观点不代表本网站立场;本网站视频或图片制作权归当前商户及其作者,涉及未经授权的制作均须标记“样稿”。如内容侵犯了您相关权利,请及时通过邮箱service@ichub.com与我们联系。
     0  0

    微信扫一扫:分享

    微信里点“+”,扫一扫二维码

    便可将本文分享至朋友圈。

      
    
    
    分享
     0
      验证