news 2026/9/23 17:42:13

使用 LanceDB JavaScript SDK 构建向量检索应用:安装、连接、建表与向量搜索实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 LanceDB JavaScript SDK 构建向量检索应用:安装、连接、建表与向量搜索实战
  • 向量数据库
  • 数据库
  • 人工智能
  • 后端

【免费下载链接】lancedb

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

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

本篇文章以 LanceDB 官方 JavaScript SDK(@lancedb/lancedb)为主线,系统讲解如何在 Node.js 应用中完成安装、建立连接、创建/写入数据表、执行向量检索与全文搜索,并结合仓库源码剖析connectcreateTablevectorSearch等核心 API 的底层实现与调用链。读完本文,你将能够从零搭建一个可运行的嵌入式向量检索应用,并具备深入阅读 SDK 源码、二次开发与调试的能力。

LanceDB JavaScript SDK 概览

LanceDB 是一个面向多模态 AI 场景的开发者友好型开源嵌入式向量数据库,其核心价值在于"少管理、多检索"(Search More; Manage Less):无需独立部署数据库服务,直接在应用进程内以库的形式运行。JavaScript SDK 则是 LanceDB 在 Node.js/TypeScript 生态中的官方接入层,包名为@lancedb/lancedb(见 nodejs/package.json)。

从源码结构看,该 SDK 采用Rust 核心 + napi-rs 绑定的架构:

  • nodejs/src/:Rust 绑定层源码,负责与 LanceDB 核心库交互;
  • nodejs/lancedb/:TypeScript 包源码,面向开发者的公开 API 全部从这里导出;
  • nodejs/__test__/:单元测试(基于 Jest);
  • nodejs/examples/:文档配套的可运行示例(pnpm workspace)。

这一架构意味着:所有重计算(索引构建、向量距离计算、列式存储读写)都发生在原生层,而 JS 层负责提供类型安全的、Promise 化的开发体验。入口文件 nodejs/lancedb/index.ts 一次性导出了连接、表、查询、索引、嵌入函数、重排序(rerankers)、物化视图等全部公开类型与函数,是理解整个 SDK 能力边界的起点。

环境要求与安装

安装命令

npm install @lancedb/lancedb

安装时 npm 会自动下载与你当前平台匹配的原生库(每个平台发布为独立的 npm 包,见 nodejs/npm/ 下的darwin-arm64linux-x64-gnuwin32-x64-msvc等目录)。当前仓库支持的平台包括:

  • Linux:x86_64 与 aarch64,同时支持 glibc 与 musl;
  • macOS:Intel(x86_64)与 Apple Silicon(ARM/M1/M2,aarch64);
  • Windows:x86_64 与 aarch64。

与 nodejs/package.json 中napi.targets声明的编译目标一一对应,即aarch64-apple-darwinx86_64-unknown-linux-gnuaarch64-unknown-linux-gnux86_64-unknown-linux-muslaarch64-unknown-linux-muslx86_64-pc-windows-msvcaarch64-pc-windows-msvc

运行环境约束

根据 nodejs/package.json 中的声明,使用时还需注意:

  • Node.js 版本engines.node >= 22
  • Apache Arrow:作为 peerDependency,要求apache-arrow >= 15.0.0 且 <= 18.1.0(SDK 与 Arrow 数据格式深度耦合,Arrow 数据、Schema、RecordBatch 都直接来自该库);
  • 可选依赖openai(OpenAI 嵌入函数)与@huggingface/transformers(本地 Transformers 嵌入函数)按需安装即可;
  • 包管理器在仓库内使用 pnpm 11(packageManager: pnpm@11.1.1),发布版本为0.40.0-beta.5,License 为 Apache-2.0。

快速上手:从连接到向量搜索

nodejs/README.md 给出了一个最小可运行的完整示例,这是理解 SDK 用法的最佳起点:

import * as lancedb from "@lancedb/lancedb"; // 1. 连接:创建(或打开)本地数据库目录 const db = await lancedb.connect("data/sample-lancedb"); // 2. 建表:用普通 JS 对象数组初始化一张表,自动推导 schema const table = await db.createTable("my_table", [ { id: 1, vector: [0.1, 1.0], item: "foo", price: 10.0 }, { id: 2, vector: [3.9, 0.5], item: "bar", price: 20.0 }, ]); // 3. 向量搜索:返回与查询向量最相似的 20 条记录 const results = await table.vectorSearch([0.1, 0.3]).limit(20).toArray(); console.log(results);

这个例子覆盖了 SDK 的三个核心动作:

  1. connect(uri)—— 建立数据库连接。传入本地目录路径时即创建嵌入式数据库;
  2. createTable(name, data)—— 以普通对象数组建表。SDK 会将数据转换为 Arrow IPC 格式交给原生层(parseTableDatafromTableToBuffer,见 nodejs/lancedb/connection.ts),字段vector会被识别为向量列;
  3. vectorSearch(vector)—— 发起近似最近邻(ANN)检索,返回包含原始字段与距离的匹配行。

源码视角:vectorSearch 到底做了什么

vectorSearchTable上的便捷方法,其实现位于 nodejs/lancedb/table.ts:

vectorSearch(vector: IntoVector | MultiVector): VectorQuery { if (isMultiVector(vector)) { const query = this.query().nearestTo(vector[0]); for (const v of vector.slice(1)) { query.addQueryVector(v); } return query; } return this.query().nearestTo(vector); }

可以看到它内部委托给query().nearestTo(vector),构建一个VectorQuery查询构建器(见 nodejs/lancedb/query.ts)。VectorQuery支持链式调用.limit().select().offset().filter().distanceType()等,最后通过.toArray()(或.toArrow()、异步迭代RecordBatch)触发执行。

测试用例 nodejs/test/query.test.ts 验证了向量搜索返回的 schema 中除所选列外还会追加一个_distance字段(Float32 类型),用于表示每条结果与查询向量的距离;同时验证了offset是在limit之后应用的,可据此实现稳定的分页:

// 第二页:先取前 4 条再跳过 2 条 const secondPage = await table .vectorSearch([0, 0]) .select(["id"]) .limit(2) .offset(2) .toArray();

连接管理:URI 格式、选项与多种连接方式

connect的完整签名与实现位于 nodejs/lancedb/index.ts。它支持两种调用形式:

// 形式一:connect(uri, options?, session?, headerProvider?) const conn = await lancedb.connect("/path/to/database"); const conn2 = await lancedb.connect("s3://bucket/path/to/database", { storageOptions: { timeout: "60s" }, }); // 形式二:connect(options & { uri }) const conn3 = await lancedb.connect({ uri: "/path/to/database", session: Session.default(), });

支持的 URI 格式

  • /path/to/database—— 本地文件系统数据库;
  • s3://bucket/pathgs://bucket/path—— 云对象存储上的数据库(通过storageOptions传入访问凭证、超时等配置);
  • db://host:port—— 远程数据库(LanceDB Cloud),此时可配合headerProvider做每请求鉴权(例如StaticHeaderProvider注入X-API-Key)。

内部实现上,connect会通过LanceDbConnection.new(uri, finalOptions, nativeProvider)创建原生连接,再包装成LocalConnection返回(见 nodejs/lancedb/connection.ts)。

storageOptions 的规范化

传入的存储选项会经过cleanseStorageOptions处理(nodejs/lancedb/connection.ts):所有键会被统一转换为 snake_case后再传给原生层。因此你既可以用{ timeout: "60s" }也可以用{ "timeout": "60s" },SDK 会保证兼容。

connectNamespace:目录 / REST 命名空间 / 自定义实现

除按 URI scheme 路由的connect外,SDK 还提供connectNamespace(implName, config, options?)(nodejs/lancedb/index.ts),用于通过命名空间实现连接:

  • "dir"—— 目录命名空间,配置{ root: "/path/to/db", manifestEnabled?, extraProperties? },所有表存放于单一根路径下;
  • "rest"—— REST 目录服务,配置{ uri: "https://catalog.example.com", headers?, extraProperties? },通过 HTTP 访问远端 catalog;
  • 其他字符串 —— 自定义命名空间实现的完整模块路径,配置为自由格式的properties字符串映射。

连接生命周期

Connection是一个长生命周期对象,可能持有 HTTP 连接池等资源,官方建议在多次使用中共享同一个连接。完成使用后可调用close()主动释放资源;不关闭也会在垃圾回收时自动清理。连接关闭后再调用其方法会直接报错。此外,已创建的表是独立对象,即使底层连接被关闭,表仍可继续工作(见 nodejs/lancedb/connection.ts 中Connection类文档)。

建表与数据写入

createTable 的多种重载与选项

createTable支持多种重载形式(名称+数据、options 对象、命名空间路径),公共选项见CreateTableOptions(nodejs/lancedb/connection.ts):

选项类型说明
mode"create" \| "overwrite""create"时若表已存在则报错(除非existOk为 true);"overwrite"直接替换已有表
existOkboolean表已存在且 mode 为"create"时不报错(内部转换为"exist_ok"
schemaSchemaLike显式指定 schema,替代自动推导
embeddingFunctionEmbeddingFunctionConfig配置自动嵌入函数,写入时自动生成向量
storageOptionsRecord<string, string>对象存储配置,继承连接配置但可覆盖
dataStorageVersion/enableV2ManifestPaths已废弃分别迁移到newTableDataStorageVersionnewTableEnableV2ManifestPaths存储选项

值得注意的实现细节:在LocalConnection.createTable_createTableImpl)中,dataStorageVersionenableV2ManifestPaths这两个已废弃字段会被自动改写进 storageOptions(见 nodejs/lancedb/connection.ts),保证向后兼容。

创建空表与增量写入

// 创建空表(需要显式 schema) await db.createEmptyTable("empty_table", schema); // 增量写入:追加 or 覆盖 const result = await table.add(newRows); // 默认 append const result2 = await table.add(newRows, { mode: "overwrite" }); // 监听写入进度 await table.add(data, { progress: (p) => { console.log(`${p.outputRows}/${p.totalRows ?? "?"} rows`); }, });

AddDataOptionsprogress回调(nodejs/lancedb/table.ts)会按批次触发,并在结束时以done: true回调一次;回调异常只会console.warn记录而不会中断写入。add返回的AddResult包含新的表版本号。

此外,Table还提供update(支持 SQL 条件wherevaluesvaluesSql)、deletemergeInsertMergeInsertBuilder)等数据变更能力,均返回包含影响行数与版本号的 Result 对象。

表管理:打开、列举、删除与命名空间

打开与分页列举

// 打开表,可选 branch(分支)与 version(版本钉定) const table = await db.openTable("my_table", { branch: "feature-branch", version: 42, // 只读视图,配合 checkoutLatest 恢复可写 }); // 分页列举表(pageToken 为不透明令牌) const names: string[] = []; let pageToken = undefined; do { const page = await conn.listTables({ pageToken, limit: 100 }); names.push(...page.tables); pageToken = page.pageToken; } while (pageToken);

openTable的实现(nodejs/lancedb/connection.ts)会先打开表,再根据branch/version选项自动执行分支检出或版本钉定;"main"被视为默认分支从而跳过额外操作。

删除与清理

  • dropTable(name):同步删除;
  • dropTableAsync(name):返回Job,可等待物理文件清理完成(表可能在清理完成前就已不可用);
  • dropAllTables():清空数据库。

Job是 SDK 中异步后台任务的一等公民:Connection还提供openJob(jobId)listJobs()cancelJob(jobId)来追踪服务端任务状态。

命名空间(Namespace)

命名空间用于对表进行层级组织,相关 API 全部在Connection上:

  • createNamespace(path, { mode: "create" | "exist_ok" | "overwrite", properties })
  • listNamespaces(path?, { pageToken, limit })describeNamespace(path)
  • dropNamespace(path, { mode: "skip" | "fail", behavior: "restrict" | "cascade" })——"restrict"拒绝删除非空命名空间,"cascade"递归删除其中所有内容。

克隆与重命名

cloneTable(targetName, sourceUri, options)支持浅克隆(默认isShallow: true):新表与源表共享底层数据文件,但拥有独立 manifest,可各自演进。renameTable则目前仅 LanceDB Cloud 支持,本地连接与命名空间连接会返回 "not supported" 错误(见Connection类文档)。

检索:向量搜索、全文搜索与查询构建器

查询构建器通用能力

QueryBase(nodejs/lancedb/query.ts)是所有查询(Query/VectorQuery/TakeQuery)的公共基类,提供:

  • select(...):投影所需列,显著降低列式存储的 I/O 延迟;也支持动态列,如new Map([["combined", "a + b"]])(SQL 表达式)——这是官方建议的实践;
  • limit(n)/offset(n):分页(注意 offset 在 limit 之后应用,见测试用例);
  • orderBy(...):按列排序(支持升降序与 null 优先级);
  • filter(expr):SQL 过滤表达式;
  • distanceType(type):向量距离度量(默认"l2";nodejs/lancedb/indices.ts 中特别强调:索引训练时使用的距离类型必须与检索时一致,否则结果不准确);
  • 终端操作.toArray()返回行对象数组;查询对象本身也是AsyncIterable<RecordBatch>,可用for await逐批消费,并通过QueryExecutionOptionsmaxBatchLengthtimeoutMs)控制执行。

向量检索与全文检索

// 向量检索(自动追加 _distance 列) await table.vectorSearch([0.1, 0.3]).limit(20).toArray(); // 全文检索:先创建 FTS 索引 await table.createIndex("text", { config: Index.fts() }); await table.search("foo", "fts").select(["id"]).limit(10).toArray();

全文检索结果会附带_score字段(由 nodejs/test/query.test.ts 的 schema 断言确认)。FTS 索引支持 tokenizer 配置(simple等基础分词器、语言、停用词、词干化、ngram 等),Table还导出tokenize函数,可在不建索引的情况下直接分词(见 nodejs/lancedb/index.ts 的TokenizeOptions)。

search() 的自动路由

Table.search(query, queryType = "auto")(nodejs/lancedb/table.ts)会根据参数自动路由:

  • 传入向量 → 走vectorSearch
  • queryType: "fts"→ 走全文搜索;
  • queryType: "auto"且表配置了嵌入函数 → 由嵌入函数计算查询向量后执行向量检索(computeQueryEmbeddings)。

对于多向量混合检索,SDK 还提供了rerankers模块(如RRFReranker,见 nodejs/lancedb/rerankers/rrf.ts),用于融合多路检索结果。

索引:让检索从暴力扫描走向 ANN

Table.createIndex配合Index工厂(nodejs/lancedb/indices.ts)可创建多种索引:

  • Index.ivfPq(options):IVF + 乘积量化,最常用的 ANN 索引,关键参数:
    • numPartitions:IVF 分区数,默认取行数的平方根;过大则选分区慢,过小则分区内搜索慢;
    • numSubVectors:PQ 子向量数,控制压缩率,默认dim / 16(不可整除时dim / 8,以便利用 SIMD 指令);
    • numBits:每个子向量的量化位数,必须为 4 或 8,默认 8;
    • distanceType:距离度量,默认"l2",必须与检索一致;
  • Index.hnswSq(options)/Index.hnswPq(options):基于 HNSW 的图索引;
  • Index.fts(options):全文索引,支持 tokenizer 与语言配置;
  • Index.ivfFlat/Index.ivfRq:其他向量索引变体。

索引构建是异步任务,可用Job追踪进度。数据集较大时合理选择numPartitions与量化位数,是在召回率与延迟之间做权衡的关键(索引配置的完整类型见 nodejs/lancedb/indices.ts 的IvfPqOptions等接口)。

自动嵌入:Embedding 注册表与内置嵌入函数

SDK 提供了一等公民的嵌入函数体系,让"写入时自动生成向量、检索时自动嵌入查询"成为可能:

  • nodejs/lancedb/embedding/目录下内置了openai.ts(OpenAI 嵌入模型)与transformers.ts(本地 HuggingFace Transformers 模型);
  • 所有嵌入函数继承自抽象的EmbeddingFunction(nodejs/lancedb/embedding/embedding_function.ts),实现computeQueryEmbeddings/ 文本编码等接口;
  • 通过EmbeddingFunctionRegistry注册/查找函数,注册信息(含函数配置)会序列化到表元数据中,检索时可自动解析并路由。

使用方式是在建表时声明embeddingFunction

import * as lancedb from "@lancedb/lancedb"; import { getRegistry } from "@lancedb/lancedb/embedding"; // 或使用内置的 openai / transformers 嵌入函数 const db = await lancedb.connect("data/sample-lancedb"); const table = await db.createTable("documents", [ { text: "hello world", category: "greeting" }, ], { embeddingFunction: /* 注册表返回的嵌入函数配置 */, }); // 之后 table.search("任意文本") 会自动完成嵌入与检索

createEmptyTable的实现可以看到,embeddingFunction会通过registry.getTableMetadata生成表元数据(nodejs/lancedb/connection.ts),而search(..., "auto")则通过registry.parseFunctions从元数据还原嵌入函数并计算查询向量——正是这两段代码构成了"自动嵌入"的闭环。

本地开发与测试

如果你想在仓库内对 SDK 进行二次开发或运行测试,nodejs/CONTRIBUTING.md 说明了完整流程。前置条件:Node.js 22+、pnpm 11+(或corepack enable)、Rust 工具链(rustup 安装 Cargo)、以及 protoc(Protocol Buffers 编译器)。

pnpm install # 安装依赖 pnpm build # 构建原生绑定 + 编译 TypeScript pnpm lint # Biome 检查与格式化 pnpm test # 运行全部 Jest 测试 # 运行单个测试文件 pnpm test -- table.test.ts # 按名称过滤用例 pnpm test -- table.test.ts --testNamePattern=merge\ insert

构建脚本(见 nodejs/package.json 的scripts)使用napi build产出平台原生.node文件并生成native.d.ts/native.js,TypeScript 层通过lancedb/native.js与原生模块桥接——这也是理解"JS 方法 → 原生调用"链路的关键入口。

总结

LanceDB JavaScript SDK 以"嵌入式、零运维"的方式把向量数据库能力带入了 Node.js 生态:connect一行完成连接、createTable用普通对象数组建表、vectorSearch链式调用完成 ANN 检索,全程无需管理任何服务进程。在此基础上,本文进一步结合仓库源码剖析了connect的 URI 路由与 options 规范化、vectorSearchnearestTo的委托链路、createTable的多种模式与选项、分页/命名空间/物化视图等表管理能力,以及索引参数与自动嵌入函数的底层机制。若需查看更多完整示例,可继续阅读 nodejs/README.md、docs/src/js/README.md 与 nodejs/examples/ 中的可运行代码,或直接阅读 nodejs/test/ 下的测试用例验证各 API 的实际行为。

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

【免费下载链接】lancedb

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

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

相关推荐

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 17:42:15

5个坑搞定极品飞车5下载源码剖析

5个坑搞定极品飞车5下载源码剖析 别再去翻那几百页的官方文档了,真正能让你在实战项目里站稳脚跟的,往往是那些被忽略的细节。 做后端开发,我们总以为“下载”就是 file.download() 这么简单。但当你接手一个类似 极品飞车5下载 这种高并发、大文件的 实战项目…

作者头像 李华
网站建设 2026/9/23 17:42:12

U-Net轻量语义分割实现工地裂缝像素级识别

简介&#xff1a;本资源是西南交通大学《智能建造与运维养》课程的实践型作业文档&#xff0c;面向土木工程、智能建造及相关专业本科生&#xff0c;聚焦结构表面裂缝的像素级智能识别问题&#xff0c;系统融合卷积神经网络、图像语义分割与TensorFlow工程实现。文档完整覆盖从…

作者头像 李华
网站建设 2026/9/23 17:41:55

毕业报告代码烂到哭?3个源码级最佳实践让面试官闭嘴

毕业报告代码烂到哭?3个源码级最佳实践让面试官闭嘴 面试时被问:“你那个毕业报告里的缓存模块,底层是怎么实现的?” 你支支吾吾,只能说出用了 Redis,却答不上来为什么穿透了。 这种“只知其然不知其所以然”的状态,是技术新人的致命伤,也是项目现场管理员最头疼的隐患。…

作者头像 李华
网站建设 2026/9/23 17:41:49

新手避坑指南:从零手写七大手法,拒绝官方文档劝退

新手避坑指南:从零手写七大手法,拒绝官方文档劝退 官方文档翻了三遍还是晕?别急,新手避坑第一步就是扔掉那些晦涩的理论。 很多人卡在概念里出不来,其实七大手法就是为了解决“现场乱、查不到、改不动”这三个烂摊子。 今天咱们不背八股文,直接上手写一个最小可用版本,把原理跑通。 项目目标…

作者头像 李华
网站建设 2026/9/23 17:41:34

ODF源码解析:面试原理答不上来?看这篇就够了

ODF源码解析:面试原理答不上来?看这篇就够了 面试被问“ODF文件结构底层是怎么组织的”,你如果只能答出“它是XML”,大概率直接挂掉。很多开发者平时只管用 odfpy 或者 Apache POI 读写字典,真到了拷问原理的环节,往往卡壳。 ODF(OpenDocument…

作者头像 李华
网站建设 2026/9/23 17:41:04

搞定shor环境配置,面试必问的高频考点一次讲透

搞定shor环境配置,面试必问的高频考点一次讲透 配置环境就卡半天,是不是你的常态?每次为了搞通一个基础库,折腾一下午,结果面试时被问得哑口无言。别急,今天咱们直接切入正题,针对【shor】这个高频面试必问点,把原理、代码和避坑指南一次性拆解清楚。…

作者头像 李华