Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

索引自省

VSAG 提供三类自省 API,让调用方可以发现某个索引的能力、对已有向量计算距离,以及读出关于已构建 索引的结构化信息,而无需重新执行一次搜索:

  • CheckFeature(IndexFeature) —— 运行时能力探测。
  • CalDistanceById(...) —— 计算 query 到已存入向量 id 的距离。
  • GetIndexDetailInfos() / GetDetailDataByName(...) —— 读取索引各项结构化详情数据。

这些 API 均为只读操作,可与搜索并发调用。

能力探测 —— CheckFeature

当底层索引实现公布了某项能力时,index->CheckFeature(vsag::SUPPORT_*) 返回 true。当代码路径 持有一个具体类型未知的 IndexPtr(例如用户配置注入、多态存储)时,应使用此 API:

if (index->CheckFeature(vsag::SUPPORT_ESTIMATE_MEMORY)) {
    uint64_t est = index->EstimateMemory(100'000);
}

if (not index->CheckFeature(vsag::SUPPORT_DELETE_BY_ID)) {
    // 跳过 / 通过另一个索引以 remove + re-add 方式回退。
}

能力标志几乎覆盖了库中所有可选接口:build / add / 序列化变体、各种并发组合、度量类型、属性 过滤、extra-info 过滤、CloneExportModelTune 等。完整枚举见 include/vsag/index_features.h

可运行示例:examples/cpp/307_feature_check_features.cpp

到已有 id 的距离 —— CalDistanceById

CalDistanceById 计算 query 与索引中已存在的一个或多个向量之间的距离,无需执行一次 搜索。它适用于 re-rank、A/B 评估、ground-truth 校验,或对已知候选集合做成对距离计算。

提供两个重载:

// 稠密向量索引(HGraph、BruteForce、IVF、DiskANN、HNSW)
auto r = index->CalDistanceById(query_ptr, ids, count, /*calculate_precise_distance=*/true);

// 稀疏向量索引(SINDI、SparseIndex)—— 用 Dataset 封装查询
auto query_ds = vsag::Dataset::Make();
query_ds->NumElements(1)->SparseVectors(/* ... */);
auto r = index->CalDistanceById(query_ds, ids, count, /*calculate_precise_distance=*/true);

结果 DatasetGetDistances() 持有 count 个距离。若某个 id 无效(不在索引中),对应位置 返回 -1.0F

calculate_precise_distance

末尾的 bool 参数在精度与延迟之间做取舍:

取值行为
true(默认)使用全精度向量表征。在内存-磁盘混合索引上可能引发磁盘 I/O。
false使用搜索路径缓存的量化 / 近似表征。更快、无 I/O。

可运行示例:examples/cpp/306_feature_calculate_distance_by_id.cpp

详情数据 —— GetIndexDetailInfos / GetDetailDataByName

GetIndexDetailInfos() 返回一组 IndexDetailInfo 记录,描述索引可对外暴露的每一项命名结构化 数据。每条记录包含 namedescription 和一个 type 枚举,后者用于选择 DetailData 上的 合适访问器。

是否支持取决于索引类型 —— 这两个 API 没有专门的 SUPPORT_* flag。Index 基类默认抛 std::runtime_error("Index doesn't support ...")GetIndexDetailInfosGetDetailDataByName,见 include/vsag/index.h:658,674);HGraph / IVF / BruteForce / Pyramid / SINDI / WARP 通过 InnerIndexInterface 提供了实现,而 HNSW 仅 override 了 GetDetailDataByName,DiskANN 两者都没有 override。调用时请始终处理 tl::expected 的 error 分支。

auto infos = index->GetIndexDetailInfos().value();
for (const auto& info : infos) {
    std::cout << info.name << " : " << info.description << '\n';
}

知道哪些项可用后,调用 GetDetailDataByName(name, info) 获取对应类型的数据:

vsag::IndexDetailInfo info;
auto detail = index->GetDetailDataByName(vsag::INDEX_DETAIL_NAME_NUM_ELEMENTS, info).value();
int64_t n = detail->GetDataScalarInt64();

detail = index->GetDetailDataByName(vsag::INDEX_DETAIL_NAME_LABEL_TABLE, info).value();
auto table = detail->GetData2DArrayInt64();   // [row][col] int64 矩阵

detail = index->GetDetailDataByName(vsag::INDEX_DETAIL_DATA_TYPE, info).value();
std::string dt = detail->GetDataScalarString();

数据类型

info.type 决定 DetailData 上哪一个访问器有效:

IndexDetailDataType访问器
TYPE_SCALAR_INT64GetDataScalarInt64()
TYPE_SCALAR_DOUBLEGetDataScalarDouble()
TYPE_SCALAR_BOOLGetDataScalarBool()
TYPE_SCALAR_STRINGGetDataScalarString()
TYPE_1DArray_INT64GetData1DArrayInt64()
TYPE_2DArray_INT64GetData2DArrayInt64()

include/vsag/index_detail_info.h 中以常量形式给出的标准详情名:

常量典型类型含义
INDEX_DETAIL_NAME_NUM_ELEMENTSTYPE_SCALAR_INT64索引当前包含的向量数。
INDEX_DETAIL_NAME_LABEL_TABLETYPE_2DArray_INT64逐向量的 label 表(如内部 id ↔ 用户 id 映射)。
INDEX_DETAIL_DATA_TYPETYPE_SCALAR_STRING底层向量数据类型(如 "float32")。

具体索引可能额外暴露其他名称;运行期通过 GetIndexDetailInfos() 遍历即可发现。可运行示例: examples/cpp/317_feature_get_detail_data.cpp

注意事项与限制

  • CheckFeature 是常数时间复杂度。相比对不支持的调用做 try / catch,应优先使用它。
  • CalDistanceById 要求底层索引保留足够信息以重新计算距离。对于纯量化索引(不保留原始向量), 即使传入 calculate_precise_distance = true,也可能返回量化距离。
  • GetIndexDetailInfosGetDetailDataByName 是只读快照。返回的数值反映调用瞬间的索引状态, 并发修改可能使其失效。