点(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:
urnF9168C5E-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_vectors
和 with_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版本开始可用
您可以对多个点的更新操作进行批处理。这包括插入、更新和删除点、向量和有效载荷。
批量更新请求由一系列操作组成。这些操作按顺序执行。可以进行批处理的操作包括:
- 插入或更新点:
upsert
或UpsertOperation
- 删除点:
delete_points
或DeleteOperation
- 更新向量:
update_vectors
或UpdateVectorsOperation
- 删除向量:
delete_vectors
或DeleteVectorsOperation
- 设置有效载荷:
set_payload
或SetPayloadOperation
- 覆盖有效载荷:
overwrite_payload
或OverwritePayload
- 删除有效载荷:
delete_payload
或DeletePayloadOperation
- 清除有效载荷:
clear_payload
或ClearPayloadOperation
以下示例代码片段使用了所有操作。
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]}}
]
}
要使用单个操作类型的批量点,请直接使用该操作中的批处理功能。