一架梯子,一头程序猿,仰望星空!
Qdrant向量数据库教程 > 内容正文

Qdrant向量数据(Points)


点(points)

点(points)是Qdrant操作的核心实体。一个点是由向量(vector)和可选载荷(payload)组成的记录。

您可以根据向量(矢量)相似性搜索在一个集合中分组的点。更详细的过程描述在搜索和过滤部分中。

本节介绍如何创建和管理矢量(向量)。

任何点(point)的修改操作都是异步的,并且分为两个步骤。在第一阶段,操作将被写入预写日志中。

此刻开始,即使机器供电中断,服务也不会丢失数据。

提示:点(points)是qdrant的抽象概念,你把它当成mysql表的一行数据即可。

等待结果

如果使用&wait=false参数调用API,或者没有明确指定,客户端将会收到数据接收的确认消息:

{
    "result": {
        "operation_id": 123,
        "status": "acknowledged"
    },
    "status": "ok",
    "time": 0.000206061
}

这个响应并不意味着可以立即检索到数据。这里使用了一种最终一致性的形式。在实际更新集合的背景过程中,可能需要一小段时间。实际上,这种请求可能最终失败。如果插入大量向量,我们还建议使用异步请求以充分利用管线操作。

如果你的应用程序逻辑要求在API响应后立即可用于搜索,则使用标志?wait=true。在这种情况下,API将在操作完成后才返回结果:

{
    "result": {
        "operation_id": 0,
        "status": "completed"
    },
    "status": "ok",
    "time": 0.000206061
}

点ID

Qdrant支持使用64位无符号整数UUID作为点的标识符。

UUID字符串表示的例子如下:

  • 简单表示法:936DA01F9ABD4d9d80C702AF85C822A8
  • 连字符表示法:550e8400-e29b-41d4-a716-446655440000
  • URN: urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4

这意味着在每个请求中,可以使用UUID字符串来替代数字ID。例如:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": "5c56c793-69f3-4fbf-87e6-c4bf54c28c26",
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        }
    ]
}

以及

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        }
    ]
}

都是可以的。

上传数据点

为了优化性能,Qdrant支持批量加载数据点。也就是说,您可以在一次API调用中加载多个数据点到服务中。批量加载可以最大程度地减少网络连接的开销。

Qdrant API支持两种批量创建方式 - 记录导向和列导向。在内部,这些选项没有区别,只是为了方便交互。

使用REST API创建数据点:

PUT /collections/{collection_name}/points

{
    "batch": {
        "ids": [1, 2, 3],
        "payloads": [
            {"color": "red"},
            {"color": "green"},
            {"color": "blue"}
        ],
        "vectors": [
            [0.9, 0.1, 0.1],
            [0.1, 0.9, 0.1],
            [0.1, 0.1, 0.9]
        ]
    }
}

或者使用记录导向的等效方式:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "payload": {"color": "red"},
            "vector": [0.9, 0.1, 0.1]
        },
        {
            "id": 2,
            "payload": {"color": "green"},
            "vector": [0.1, 0.9, 0.1]
        },
        {
            "id": 3,
            "payload": {"color": "blue"},
            "vector": [0.1, 0.1, 0.9]
        }
    ]
}

Qdrant中的所有API,包括数据点加载都是幂等的。这意味着连续执行相同的方法与单次执行等效。

在这种情况下,这意味着重新上传时具有相同id的数据点将被覆盖。

幂等性属性对于使用不提供准确一次性保证的消息队列非常有用。即使在这种情况下,Qdrant也确保数据的一致性。

自v0.10.0版本可用

如果创建的集合具有多个向量,可以使用向量的名称提供每个向量的数据:

PUT /collections/{collection_name}/points

{
    "points": [
        {
            "id": 1,
            "vector": {
                "image": [0.9, 0.1, 0.1, 0.2],
                "text": [0.4, 0.7, 0.1, 0.8, 0.1, 0.1, 0.9, 0.2]
            }
        },
        {
            "id": 2,
            "vector": {
                "image": [0.2, 0.1, 0.3, 0.9],
                "text": [0.5, 0.2, 0.7, 0.4, 0.7, 0.2, 0.3, 0.9]
            }
        }
    ]
}

自v1.2.0版本可用

命名向量是可选的。在上传数据点时,某些向量可能被省略。例如,您可以上传一个只具有image向量的数据点,和一个只具有text向量的数据点。

当修改具有现有ID的数据点时,首先删除现有的数据点,然后使用指定的向量插入它。换句话说,整个数据点将被替换,未指定的向量将设置为null。如果要保持现有向量不变,而只更新指定的向量,请参见更新向量。

修改数据点

要修改一个数据点,可以修改其向量或其载荷。有几种方法可以做到这一点。

更新向量

从版本v1.2.0开始可用

该方法更新给定点上的指定向量。未指定的向量将保持不变。所有给定的点都必须存在。

REST API (Schema):

PUT /collections/{collection_name}/points/vectors

{
    "points": [
        {
            "id": 1,
            "vector": {
                "image": [0.1, 0.2, 0.3, 0.4]
            }
        },
        {
            "id": 2,
            "vector": {
                "text": [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]
            }
        }
    ]
}

要更新点并替换所有向量,请参见上传点。

删除向量

从版本v1.2.0开始可用

该方法仅从给定点中删除指定的向量。其他向量将保持不变。不会删除点。

REST API (Schema):

POST /collections/{collection_name}/points/vectors/delete

{
    "points": [0, 3, 100],
    "vectors": ["text", "image"]
}

设置负载

在点上设置给定的负载值。

REST API (Schema):

POST /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "points": [
        0, 3, 100
    ]
}

您不需要知道要修改的点的id。另一种方法是使用过滤器。

POST /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

覆盖负载

完全用给定的负载替换现有的负载。

REST API (Schema):

PUT /collections/{collection_name}/points/payload

{
    "payload": {
        "property1": "string",
        "property2": "string"
    },
    "points": [
        0, 3, 100
    ]
}

与[设置负载](#set-payload)一样,您不需要知道要修改的点的id。另一种方法是使用过滤器。

删除负载键

REST API (Schema):

POST /collections/{collection_name}/points/payload/delete

{
    "keys": ["color", "price"],
    "points": [0, 3, 100]
}

或者,您可以使用过滤器从点中删除负载键。

POST /collections/{collection_name}/points/payload/delete

{
    "keys": ["color", "price"],
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

清除负载

此方法从指定的点中删除所有负载键。

REST API (Schema):

POST /collections/{collection_name}/points/payload/clear

{
    "points": [0, 3, 100]
}

删除点

REST API (Schema):

POST /collections/{collection_name}/points/delete

{
    "points": [0, 3, 100]
}

另一种指定要删除的点的方式是使用过滤器:

POST /collections/{collection_name}/points/delete

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    }
}

该示例从集合中删除所有 { "color": "red" } 的点。

检索点

通过其id检索点的方法:

REST API (Schema):

POST /collections/{collection_name}/points

{
    "ids": [0, 3, 100]
}

此方法有额外的参数 with_vectorswith_payload。使用这些参数,您可以选择所需的点结果的部分。排除帮助您不浪费流量传输无用的数据。

也可以通过API检索单个点:

REST API (Schema):

GET /collections/{collection_name}/points/{point_id}

scroll

有时候需要获取所有存储的点,但不知道id,或者迭代满足过滤条件的点。

REST API (Schema):

POST /collections/{collection_name}/points/scroll

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    },
    "limit": 1,
    "with_payload": true,
    "with_vector": false
}

返回满足color=red的所有点:

{
    "result": {
        "next_page_offset": 1,
        "points": [
            {
                "id": 0,
                "payload": {
                    "color": "red"
                }
            }
        ]
    },
    "status": "ok",
    "time": 0.0001
}

Scroll API将以逐页的方式返回与过滤器匹配的所有点。

所有结果点按ID排序。要查询下一页,需要在offset字段中指定最大发现的ID。为了方便起见,此ID还返回在next_page_offset字段中。如果next_page_offset字段的值为null-已到达最后一页。

计算点的数量

从v0.8.4版本开始可用

有时,仅仅知道有多少点符合过滤条件,而无需进行真正的搜索,是很有用的。

例如,我们可以突出显示以下几种场景:

  • 用于分面搜索的结果大小评估
  • 确定分页的页数
  • 调试查询执行速度

REST API (Schema):

POST /collections/{collection_name}/points/count

{
    "filter": {
        "must": [
            {
                "key": "color",
                "match": {
                    "value": "red"
                }
            }
        ]
    },
    "exact": true
}

返回符合给定过滤条件的计数数量:

{
    "count": 3811
}

批量更新

从v1.5.0版本开始可用

您可以对多个点的更新操作进行批处理。这包括插入、更新和删除点、向量和有效载荷。

批量更新请求由一系列操作组成。这些操作按顺序执行。可以进行批处理的操作包括:

  • 插入或更新点:upsertUpsertOperation
  • 删除点:delete_pointsDeleteOperation
  • 更新向量:update_vectorsUpdateVectorsOperation
  • 删除向量:delete_vectorsDeleteVectorsOperation
  • 设置有效载荷:set_payloadSetPayloadOperation
  • 覆盖有效载荷:overwrite_payloadOverwritePayload
  • 删除有效载荷:delete_payloadDeletePayloadOperation
  • 清除有效载荷:clear_payloadClearPayloadOperation

以下示例代码片段使用了所有操作。

REST API(架构):

POST /collections/{collection_name}/points/batch

{
    "operations": [
        {
            "upsert": {
                "points": [
                    {
                        "id": 1,
                        "vector": [1.0, 2.0, 3.0, 4.0],
                        "payload": {}
                    }
                ]
            }
        },
        {
            "update_vectors": {
                "points": [
                    {
                        "id": 1,
                        "vector": [1.0, 2.0, 3.0, 4.0]
                    }
                ]
            }
        },
        {
            "delete_vectors": {
                "points": [1],
                "vector": [""]
            }
        },
        {
            "overwrite_payload": {
                "payload": {
                    "test_payload": "1"
                },
                "points": [1]
            }
        },
        {
            "set_payload": {
                "payload": {
                    "test_payload_2": "2",
                    "test_payload_3": "3"
                },
                "points": [1]
            }
        },
        {
            "delete_payload": {
                "keys": ["test_payload_2"],
                "points": [1]
            }
        },
        {
            "clear_payload": {
                "points": [1]
            }
        },
        {"delete": {"points": [1]}}
    ]
}

要使用单个操作类型的批量点,请直接使用该操作中的批处理功能。



关联主题