跳转至

点操作 API

本文件面向“点操作”API,系统性地记录与实现相关的 HTTP 端点:PUT /collections/{name}/points(Upsert 点)、POST /collections/{name}/points/search(搜索)、POST /collections/{name}/points/delete(删除)。文档涵盖:

  • 端点请求/响应模式与字段定义
  • PointStruct 结构、向量数据格式、过滤条件语法
  • Upsert 批量插入、更新与覆盖机制
  • 搜索查询参数配置(向量、过滤器、限制数量)
  • 删除操作的多种方式(按 ID 与按过滤条件)
  • 完整的 JSON 示例与错误处理说明

项目结构

该服务采用分层设计:

  • API 层:负责路由与 HTTP 协议编解码
  • 核心层:Collection、Index、Storage 等业务逻辑
  • 存储层:基于 bbolt 的本地持久化,配合 Protobuf 序列化
graph TB
subgraph "API 层"
S["Server
路由与HTTP处理"] end subgraph "核心层" C["Collection
集合管理"] I["VectorIndex
索引接口"] F["Flat/HNSW 索引"] M["Models
PointStruct/Filter/ScoredPoint"] D["Distance
Cosine/Euclid/Dot"] end subgraph "存储层" ST["Storage
bbolt + Protobuf"] end S --> C C --> I I --> F C --> ST M --> D

核心组件

  • Server:HTTP 路由与请求处理,暴露点操作端点
  • Collection:集合抽象,封装 Upsert/Search/Delete 业务
  • VectorIndex 接口:统一的索引能力(Upsert/Search/Delete/Count/Filter)
  • Storage:本地持久化,支持 bbolt 与 Protobuf 序列化
  • Models:数据模型(PointStruct、Filter、ScoredPoint)与匹配算法
  • Distance:距离度量(Cosine/Euclid/Dot)

架构总览

点操作 API 的调用链路如下:

sequenceDiagram
participant Client as "客户端"
participant API as "Server.handleUpsert/Search/Delete"
participant Col as "Collection"
participant Idx as "VectorIndex"
participant St as "Storage"
Client->>API : "PUT /collections/{name}/points"
请求体 : {points : [PointStruct]} API->>Col : "Upsert(points)" Col->>St : "UpsertPoints(collection, points)" Col->>Idx : "Upsert(points)" Idx-->>Col : "OK" St-->>Col : "OK" Col-->>API : "OK" API-->>Client : "{status : 'ok', result : {operation : 'completed'}}" Client->>API : "POST /collections/{name}/points/search"
请求体 : {vector : [], filter?, limit : int} API->>Col : "Search(vector, filter, limit)" Col->>Idx : "Search(vector, filter, limit)" Idx-->>Col : "[]ScoredPoint" Col-->>API : "[]ScoredPoint" API-->>Client : "{status : 'ok', result : []}" Client->>API : "POST /collections/{name}/points/delete"
请求体 : {points : [], filter?} API->>Col : "Delete(points, filter)" Col->>St : "DeletePoints(collection, ids)" Col->>Idx : "Delete(id) for each id" Idx-->>Col : "OK" St-->>Col : "OK" Col-->>API : "deleted : int" API-->>Client : "{status : 'ok', result : {operation : 'completed', deleted : int}}"

详细组件分析

点结构与过滤器模型

  • PointStruct:包含唯一标识、版本号、向量、可选负载(用于过滤)
  • ScoredPoint:搜索结果,包含相似度分数与点信息
  • Filter:支持 must/must_not 条件,条件类型包括 exact、range、prefix、contains、regex
  • Distance:支持 Cosine、Euclid、Dot 三种度量
classDiagram
class PointStruct {

    +string id
    +uint64 version
    +[]float32 vector
    +map[string]interface{
} payload
}
class ScoredPoint {

    +string id
    +uint64 version
    +float32 score
    +map[string]interface{
} payload
}
class Filter {

    +[]Condition must
    +[]Condition must_not

}
class Condition {

    +string key
    +string type
    +MatchValue match
    +RangeValue range

}
class MatchValue {

    +interface{
} value
}
class RangeValue {

    +interface{
} gt
+interface{} gte
+interface{} lt
+interface{} lte
}
class Distance {

    <>
    +Cosine
    +Euclid
    +Dot

}
ScoredPoint --> PointStruct : "包含"
Filter --> Condition : "组合"
Condition --> MatchValue : "匹配值"
Condition --> RangeValue : "范围值"
Collection ..> Distance : "使用"

Upsert 点(PUT /collections/{name}/points)

  • 功能:批量插入或更新点;若集合不存在返回 404;请求体必须为合法 JSON 返回 400;内部错误返回 500
  • 请求体字段
  • points:数组,元素为 PointStruct
  • 响应体字段
  • status:字符串,固定为 "ok"
  • result.operation:字符串,固定为 "completed"
  • 处理流程
  • 解析 JSON -> 校验集合存在 -> 调用 Collection.Upsert -> 成功返回 200 OK
sequenceDiagram
participant Client as "客户端"
participant API as "Server.handleUpsert"
participant Col as "Collection"
participant St as "Storage"
participant Idx as "VectorIndex"
Client->>API : "PUT /collections/{name}/points"
{points : [PointStruct]} API->>API : "解析JSON" API->>Col : "Upsert(points)" Col->>St : "UpsertPoints(name, points)" Col->>Idx : "Upsert(points)" Idx-->>Col : "OK" St-->>Col : "OK" Col-->>API : "OK" API-->>Client : "{status : 'ok', result : {operation : 'completed'}}"

搜索(POST /collections/{name}/points/search)

  • 功能:根据向量进行相似度检索,支持可选过滤器与限制数量
  • 请求体字段
  • vector:数组,浮点数,维度需与集合一致
  • filter:可选,Filter 对象
  • limit:整数,返回前 K 个结果,默认 10
  • 响应体字段
  • status:字符串,固定为 "ok"
  • result:数组,元素为 ScoredPoint
  • 处理流程
  • 解析 JSON -> 校验集合存在 -> 校验向量维度 -> 调用 Collection.Search -> 返回 200 OK
sequenceDiagram
participant Client as "客户端"
participant API as "Server.handleSearch"
participant Col as "Collection"
participant Idx as "VectorIndex"
Client->>API : "POST /collections/{name}/points/search"
{vector : [], filter?, limit : int} API->>API : "解析JSON" API->>Col : "Search(vector, filter, limit)" Col->>Idx : "Search(vector, filter, limit)" Idx-->>Col : "[]ScoredPoint" Col-->>API : "[]ScoredPoint" API-->>Client : "{status : 'ok', result : []}"

删除(POST /collections/{name}/points/delete)

  • 功能:支持按 ID 删除或按过滤条件删除;二者至少提供其一
  • 请求体字段
  • points:可选,字符串数组,指定要删除的点 ID
  • filter:可选,Filter 对象,匹配要删除的点
  • 响应体字段
  • status:字符串,固定为 "ok"
  • result.operation:字符串,固定为 "completed"
  • result.deleted:整数,实际删除的点数量
  • 处理流程
  • 解析 JSON -> 校验集合存在 -> 计算目标 ID 列表(ID 或通过过滤器推导)-> 先删除存储再删除索引 -> 返回 200 OK
sequenceDiagram
participant Client as "客户端"
participant API as "Server.handleDelete"
participant Col as "Collection"
participant St as "Storage"
participant Idx as "VectorIndex"
Client->>API : "POST /collections/{name}/points/delete"
{points : [], filter?} API->>API : "解析JSON" API->>Col : "Delete(points, filter)" alt 提供 points Col->>St : "DeletePoints(name, ids)" Col->>Idx : "Delete(id) for each id" else 提供 filter Col->>Idx : "GetIDsByFilter(filter)" Col->>St : "DeletePoints(name, ids)" Col->>Idx : "Delete(id) for each id" end Idx-->>Col : "OK" St-->>Col : "OK" Col-->>API : "deleted : int" API-->>Client : "{status : 'ok', result : {operation : 'completed', deleted : int}}"

过滤器语法与匹配规则

  • Filter
  • must:所有条件都必须满足
  • must_not:任何条件都不能满足
  • Condition
  • key:负载中的键名
  • type:匹配类型
    • exact:精确相等
    • range:数值范围比较(gt/gte/lt/lte)
    • prefix:字符串前缀匹配
    • contains:数组/字符串包含
    • regex:正则表达式匹配
  • match:匹配值
  • range:范围值对象
  • 匹配算法
  • 数值范围:支持 int 与 float64
  • 字符串前缀:长度检查
  • 数组/字符串包含:逐项比较
  • 正则:编译并匹配
flowchart TD
Start(["进入过滤匹配"]) --> Nil{"Filter为空?"}
Nil --> |是| TrueAll["返回true全部匹配"]
Nil --> |否| Must["遍历must条件"]
Must --> MustAll{"全部满足?"}
MustAll --> |否| FalseAll["返回false"]
MustAll --> |是| MustNot["遍历must_not条件"]
MustNot --> None{"任一满足?"}
None --> |是| FalseAll
None --> |否| TrueAll

向量数据格式与度量

  • 向量:[]float32,维度需与集合一致
  • 度量:
  • Cosine:[-1, 1],值越大越相似
  • Euclid:[0, +∞),值越小越相似
  • Dot:(-∞, +∞),值越大越相似
  • 默认度量为 Cosine

端点与错误码

  • PUT /collections/{name}/points
  • 200:成功
  • 400:无效 JSON
  • 404:集合不存在
  • 500:内部错误
  • POST /collections/{name}/points/search
  • 200:成功
  • 400:无效 JSON
  • 404:集合不存在
  • 500:内部错误
  • POST /collections/{name}/points/delete
  • 200:成功
  • 400:无效 JSON
  • 404:集合不存在
  • 500:内部错误

依赖分析

  • API 层依赖核心层的 Collection 与 Index 接口
  • Collection 依赖 VectorIndex 与 Storage
  • Storage 依赖 bbolt 与 Protobuf
  • Models 与 Distance 为纯数据与计算层
graph LR
API["api/server.go"] --> COL["core/collection.go"]
COL --> IDX["core/index.go"]
COL --> ST["core/storage.go"]
COL --> MOD["core/models.go"]
MOD --> MATH["core/math.go"]
ST --> PB["core/proto/point.proto"]

性能考虑

  • 索引选择:Flat(内存暴力)与 HNSW(图近似)可切换,HNSW 在大规模场景下具备更优的查询延迟
  • 持久化顺序:先写存储再更新索引,保证一致性与可恢复性
  • 向量量化:可启用 SQ8 量化以降低磁盘占用与加载成本
  • 查询默认限制:未显式设置 limit 时默认返回前 10 条结果

故障排除指南

  • 集合不存在
  • 现象:404 Not Found
  • 排查:确认集合名称正确且已创建
  • JSON 解析失败
  • 现象:400 Bad Request
  • 排查:检查请求体是否为合法 JSON
  • 向量维度不匹配
  • 现象:Search 时返回 500 内部错误
  • 排查:确保 vector 维度与集合一致
  • 删除参数缺失
  • 现象:Delete 返回 500 内部错误(提示必须提供 points 或 filter)
  • 排查:至少提供 points 或 filter 其中之一

结论

点操作 API 提供了与 Qdrant 兼容的 REST 接口,覆盖 Upsert、Search、Delete 三大核心能力。通过 Collection 抽象与 VectorIndex 接口,系统在一致性、可扩展性与性能之间取得平衡。建议在生产环境结合 HNSW 索引与向量量化以获得最佳吞吐与延迟表现。

附录

端点定义与示例

  • Upsert(PUT /collections/{name}/points)
  • 请求体
    • points:数组,元素为 PointStruct
    • id:字符串,唯一标识
    • version:整数,版本号(自动赋值)
    • vector:数组,浮点数,维度需与集合一致
    • payload:可选,键值对,用于过滤
  • 响应体

    • status:字符串,固定为 "ok"
    • result.operation:字符串,固定为 "completed"
  • 搜索(POST /collections/{name}/points/search)

  • 请求体
    • vector:数组,浮点数,维度需与集合一致
    • filter:可选,Filter 对象
    • must:[]Condition
    • must_not:[]Condition
    • limit:整数,返回前 K 个结果,默认 10
  • 响应体

    • status:字符串,固定为 "ok"
    • result:数组,元素为 ScoredPoint
    • id:字符串
    • version:整数
    • score:浮点数
    • payload:可选
  • 删除(POST /collections/{name}/points/delete)

  • 请求体
    • points:可选,字符串数组,指定要删除的点 ID
    • filter:可选,Filter 对象,匹配要删除的点
  • 响应体
    • status:字符串,固定为 "ok"
    • result.operation:字符串,固定为 "completed"
    • result.deleted:整数,实际删除的点数量

过滤器语法参考

  • exact:精确匹配
  • range:gt/gte/lt/lte 数值范围
  • prefix:字符串前缀
  • contains:数组/字符串包含
  • regex:正则表达式

示例请求/响应(路径引用)