LanceDB Node.js SDK 索引统计:IndexStatistics 接口字段详解与实战
2026/9/23 22:34:21 网站建设 项目流程
  • 向量数据库
  • 数据库
  • 人工智能
  • 后端

【免费下载链接】lancedb

Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.

项目地址:https://gitcode.com/gh_mirrors/la/lancedb
点击查看免费下载

导读

IndexStatistics是 LanceDB Node.js SDK(@lancedb/lancedb)中描述单个索引运行状态的核心数据结构。当你对表中的向量列、标量列或全文检索列创建索引后,可以通过Table.indexStats(name)获取该索引的统计信息,用于判断索引覆盖率、索引类型、距离度量以及分片数量。本文以官方接口文档为骨架,结合仓库中的 Rust 原生实现、TypeScript 绑定与测试用例,逐字段解读IndexStatistics的语义与取值,并给出完整的实战调用示例,帮助你掌握"建索引—查统计—评估覆盖率—决定是否重训/优化"的完整工作流。

接口概览:IndexStatistics 定义了什么

IndexStatistics接口定义于 docs/src/js/interfaces/IndexStatistics.md,它由 5 个字段组成:

字段类型是否可选含义
indexTypestring必选索引的类型
numIndexedRowsnumber必选被该索引覆盖的行数
numUnindexedRowsnumber必选未被索引覆盖的行数
distanceTypestring可选索引使用的距离函数类型,仅向量索引存在
numIndicesnumber可选该索引被拆分成的分片(part)数量

该接口并非凭空定义,而是由 Node 原生模块中的同名结构体直接映射而来。在 nodejs/src/table.rs 中,#[napi(object)]修饰的IndexStatistics结构体完整对应上述五个字段,并通过From<lancedb::index::IndexStatistics>将 Rust 核心库的统计结果转换为 JS 可读的对象。因此,文档中字段的类型语义(如num_indexed_rowsf64num_indicesOption<u32>)与底层保持一致,undefined即对应 Rust 侧的None

获取索引统计:Table.indexStats(name)

IndexStatistics的典型获取方式是调用Table.indexStats(name)

abstract indexStats(name: string): Promise<IndexStatistics | undefined>;

接口定义见 nodejs/lancedb/table.ts。需要特别注意两点:

  1. 返回值为undefined的情形:当指定名称的索引不存在时,该方法返回undefined而非抛错。实现在 nodejs/lancedb/table.ts 中,底层inner.indexStats(name)返回null时被转换为undefined
  2. 索引名称来源:索引名通常由 SDK 自动生成(如对vec列建索引会生成vec_idx),建议先通过Table.listIndices()获取索引名称列表,再逐个查询统计。

底层调用链为:Table.indexStats→ 原生table.index_stats(index_name)(nodejs/src/table.rs)→ Rust 核心库lancedb::Table::index_stats(rust/lancedb/src/table.rs)。Rust 侧的注释明确说明:索引不存在时返回None,这一语义贯穿到各语言 SDK。

完整示例:创建索引并读取统计

import * as lancedb from "@lancedb/lancedb"; const db = await lancedb.connect("data/sample-lancedb"); const table = await db.createTable("my_table", [ { id: 1, vector: [0.1, 1.0], item: "foo", price: 10.0 }, { id: 2, vector: [0.2, 0.9], item: "bar", price: 20.0 }, ]); // 1. 创建标量索引 await table.createIndex("id"); // 2. 查询统计 const stats = await table.indexStats("id_idx"); if (stats) { console.log(stats.indexType); // 例如 "BTREE" console.log(stats.numIndexedRows); // 已建索引的行数 console.log(stats.numUnindexedRows);// 尚未入索引的行数 console.log(stats.distanceType); // undefined(标量索引无距离函数) console.log(stats.numIndices); // 分片数 } // 3. 查询不存在的索引会得到 undefined const missing = await table.indexStats("some non-existent index"); console.log(missing); // undefined

字段逐项解读

indexType:索引类型

必选字段indexType: string表示索引的类型。从 Python 侧的类型定义(python/python/lancedb/table.py)可以看到,LanceDB 支持的索引类型包括向量索引(IVF_FLATIVF_SQIVF_PQIVF_RQIVF_HNSW_SQIVF_HNSW_PQIVF_HNSW_FLAT)以及标量/全文索引(FTSBTREEBITMAPLABEL_LIST)。Node SDK 中indexType为字符串,值由底层IndexType::to_string()生成(nodejs/src/table.rs)。

在 rust/lancedb/src/index.rs 的单元测试中可以看到索引类型名称的规范化逻辑:例如NGram的规范输出为NGRAMBloomFilterBLOOM_FILTERRTreeRTREE,同时兼容大小写与下划线变体解析。这意味着你在比较indexType字符串时,应以规范大写形式为准。

numIndexedRows 与 numUnindexedRows:索引覆盖率

这一对字段是评估索引健康度的核心:

  • numIndexedRows: number:被该索引覆盖的行数;
  • numUnindexedRows: number:未被该索引覆盖的行数。

Rust 核心层的定义(rust/lancedb/src/index.rs)明确指出num_unindexed_rows是"尚未被加入索引的行"(These are rows that haven't yet been added to the index)。因此,当表持续add新数据而索引未更新时,numUnindexedRows会增长;此时查询可能退化为全表扫描或部分回退,需要通过optimize()(触发索引增量更新)来提升覆盖率。

测试 python/python/tests/test_table.py 完整演示了这一生命周期:先建索引时num_indexed_rows == 2,随后add一行数据,此时再查询统计会发现已索引行数仍为 2;执行optimize()num_indexed_rows更新为 3,未索引行数归零。

distanceType:距离函数(仅向量索引)

可选字段distanceType?: string只在向量索引上存在;标量索引与全文检索(FTS)索引没有距离函数,因此该字段为undefined。文档注释(docs/src/js/interfaces/IndexStatistics.md)与 Rust 源码注释(nodejs/src/table.rs)保持一致。

从 Python 测试(python/python/tests/test_index.py)可以归纳出常见取值:

索引/场景distanceType 取值
IVF_PQ / IVF_SQ / IVF_FLAT(浮点向量)"l2"
二进制向量(IVF_FLAT)"hamming"
BITMAP / BTREE 等标量索引undefined/None

该字段本质上来自 Rust 侧的Option<DistanceType>,仅在向量索引元数据中记录metric_type(见 rust/lancedb/src/index.rs)。

numIndices:分片数量

可选字段numIndices?: number表示该索引被拆分成多少个部分(parts)。向量索引在创建时可指定numPartitions等训练参数,最终索引会被拆分为多个分片;该字段即反映这一拆分结果。在测试 nodejs/test/table.test.ts 中,默认创建索引后numIndices1

结合源码的进阶认识

统计数据的底层来源

Rust 核心库中IndexStatistics的构建来自IndexStatisticsImpl(rust/lancedb/src/index.rs),它反序列化底层 Dataset 返回的index_statistics()JSON,包含num_indexed_rowsnum_unindexed_rowsindices(其中含metric_type)和num_indices。也就是说,你在 JS 中读到的统计字段最终来源于存储引擎(Lance format)层面的索引元数据,而非实时扫描计算。

跨语言一致性

同一个概念在三种 SDK 中保持一致的语义与命名:

  • Node.jsIndexStatistics接口(本文主题),字段为 camelCase;
  • PythonIndexStatisticsdataclass(python/python/lancedb/table.py),字段为 snake_case(num_indexed_rowsdistance_type等),并保留了对旧字典式访问的兼容(__getitem__);
  • Rustlancedb::index::IndexStatistics(rust/lancedb/src/index.rs)。

Python 测试 python/python/tests/test_remote_db.py 还展示了远程云表的统计响应格式(index_typenum_indexed_rowsnum_unindexed_rows),说明该数据结构在本地嵌入模式与云服务场景下是一致的。

嵌套字段索引的统计

对于嵌套结构字段(如MetaData.userId),index_stats返回的统计同样有效,且测试覆盖了嵌套标量索引与嵌套向量索引的场景(python/python/tests/test_nested_fields.py、python/python/tests/test_nested_fields.py)。这也印证了indexStats传入的索引名(而非列名)是唯一标识,统计按索引维度聚合。

实战建议:用统计驱动索引维护

结合上述字段语义,推荐将indexStats纳入以下日常巡检流程:

  1. 建索引后立即校验numIndexedRows应等于表行数、numUnindexedRows为 0,否则说明建索引过程未完整覆盖(例如训练数据未覆盖新增分区)。
  2. 增量写入后监控:每次批量add数据后比对numUnindexedRows是否增长,据此决定是否触发optimize()更新索引。
  3. 区分索引类型分支:判断distanceType是否为undefined来区分向量索引与标量/FTS 索引,避免对不同类型索引做统一的假设。
  4. 处理 undefined 返回值indexStats对不存在的索引返回undefined,可作为"索引是否已创建"的探测手段,但注意与"索引存在但统计暂不可用"区分,必要时结合listIndices()交叉验证。
async function ensureIndexCoverage(table, indexName, expectedRows) { const stats = await table.indexStats(indexName); if (!stats) { console.warn(`索引 ${indexName} 不存在`); return; } const coverage = stats.numIndexedRows / (stats.numIndexedRows + stats.numUnindexedRows); console.log( `索引类型=${stats.indexType} 覆盖率=${(coverage * 100).toFixed(1)}% ` + `已索引=${stats.numIndexedRows} 未索引=${stats.numUnindexedRows} ` + `距离函数=${stats.distanceType ?? "N/A(非向量索引)"} 分片数=${stats.numIndices ?? "N/A"}` ); if (coverage < 1) { // 建议触发 optimize() 更新索引后再评估 console.warn(`索引 ${indexName} 尚未完全覆盖全部行`); } }

小结

IndexStatistics虽然只有五个字段,却是理解 LanceDB 索引运行状态的最小完整视图:indexType告诉你索引是什么,numIndexedRows/numUnindexedRows告诉你覆盖是否完整,distanceType告诉你向量距离度量,numIndices告诉你分片规模。通过Table.indexStats(name)即可获取,返回undefined表示索引不存在。将其与createIndexlistIndicesoptimize组合使用,即可构建一套完整的索引生命周期管理流程。本文字段语义均可在 nodejs/src/table.rs、rust/lancedb/src/index.rs 及相应测试用例中逐一验证。

  • 向量数据库
  • 数据库
  • 人工智能
  • 后端

【免费下载链接】lancedb

Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.

项目地址:https://gitcode.com/gh_mirrors/la/lancedb
点击查看免费下载

相关推荐

上一篇:7天完成传统3个月的长篇小说创作:AI智能写作工具深度解析
下一篇:实战指南:5分钟搭建高效OSINT情报分析系统

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询