- 向量数据库
- 数据库
- 人工智能
- 后端
【免费下载链接】lancedb
Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.
TokenizeTableOptions是 LanceDB Node.js 客户端中用于全文检索(Full-Text Search, FTS)查询分词的参数类型。它定义了两个互斥的分词器定位方式——按 FTS 索引所属列(column)或按 FTS 索引名称(indexName)指定要复用的分词器,供Table.tokenize()方法使用。读完本文,你将掌握该类型别名的完整定义、二选一约束的底层校验逻辑、与 FTS 索引配置的对应关系,以及如何通过测试用例验证其行为。
一、类型定义:两种互斥形态
该文档对应的类型别名定义位于 nodejs/lancedb/table.ts:
export type TokenizeTableOptions = | { /** FTS-indexed column whose tokenizer should be used. */ column: string; indexName?: never; } | { /** Name of the FTS index whose tokenizer should be used. */ indexName: string; column?: never; };这是一个 TypeScript 联合类型,两个分支分别对应:
| 形态 | 必填字段 | 说明 |
|---|---|---|
| 按列指定 | column: string | 使用该列上 FTS 索引配置的分词器 |
| 按索引名指定 | indexName: string | 使用该名称 FTS 索引配置的分词器 |
两个分支都通过?: never将另一字段声明为"禁止出现":即调用时必须且只能指定column或indexName中的一个。这种类型级约束在编译期就能拦截错误用法——如果同时传两个字段,TypeScript 会直接报类型错误。
二、使用场景:Table.tokenize() 方法
TokenizeTableOptions是Table.tokenize()方法的第二个参数类型。该方法的抽象签名位于 nodejs/lancedb/table.ts:
/** * Tokenize a full-text search query using the tokenizer configured on an FTS index. * * Specify exactly one of `column` or `indexName`. */ abstract tokenize( query: string, options: TokenizeTableOptions, ): Promise<FtsToken[]>;其实际实现(nodejs/lancedb/table.ts)将column与indexName作为两个独立参数透传给底层原生层:
async tokenize( query: string, options: TokenizeTableOptions, ): Promise<FtsToken[]> { return await this.inner.tokenize( query, options?.column, options?.indexName, ); }典型调用方式:
import { connect } from "@lancedb/lancedb"; const db = await connect("./data"); const table = await db.openTable("my_table"); // 方式一:按列名指定,复用该列 FTS 索引的分词器 const tokens1 = await table.tokenize("Running in cafés", { column: "text", }); // 方式二:按索引名称指定,复用该 FTS 索引的分词器 const tokens2 = await table.tokenize("Hello, こんにちは世界!", { indexName: "japanese_icu_idx", });返回值FtsToken[]中的每个 token 包含text(经分词器过滤后的 token 文本)与position(全文检索匹配使用的 token 位置)两个字段,其定义同样位于 nodejs/lancedb/table.ts。
三、底层实现:参数互斥校验
Node.js 层通过 N-API 绑定调用 Rust 核心实现。Rust 侧tokenize方法位于 nodejs/src/table.rs:
pub async fn tokenize( &self, query: String, column: Option<String>, index_name: Option<String>, ) -> napi::Result<Vec<FtsToken>> { let table = self.inner_ref()?; let tokens = match (column.as_deref(), index_name.as_deref()) { (Some(_), Some(_)) | (None, None) => { return Err(napi::Error::from_reason( "Specify exactly one of 'column' or 'indexName'", )); } (Some(column), None) => table.tokenize_with_column(&query, column).await, (None, Some(index_name)) => table.tokenize(&query, index_name).await, } .default_error()?; Ok(tokens.into_iter().map(FtsToken::from).collect()) }从源码结构可以看出:
- 运行时兜底校验:类型层面的
?: never约束只在编译期生效,运行时仍会检查(Some, Some)(同时传入)和(None, None)(都没传)两种非法组合,并抛出错误信息"Specify exactly one of 'column' or 'indexName'"。这意味着即使绕过 TypeScript 类型检查(例如通过as never断言或纯 JavaScript 调用),错误用法也会在运行时被拦截。 - 两条执行路径:传入
column时走tokenize_with_column路径,从列关联的 FTS 索引读取分词器配置;传入indexName时走tokenize路径,直接按索引名定位。
四、行为验证:测试用例佐证
仓库测试 nodejs/test/table.test.ts 完整验证了该类型的行为,包括非法参数的运行时错误与两种合法用法的分词结果:
// 什么都不传 -> 报错 await expect(table.tokenize("hello", {} as never)).rejects.toThrow( "Specify exactly one", ); // 同时传 column 和 indexName -> 报错 await expect( table.tokenize("hello", { column: "text", indexName: "text_idx", } as never), ).rejects.toThrow("Specify exactly one"); // 按 column 指定:simple 分词器(带词干还原) const simpleTokens = await table.tokenize("Running in cafés", { column: "text", }); expect(simpleTokens).toEqual([ { text: "run", position: 0 }, { text: "cafe", position: 2 }, ]); // 按 indexName 指定:icu 分词器(支持日文分词) const icuTokens = await table.tokenize("Hello, こんにちは世界!", { indexName: "japanese_icu_idx", }); expect(icuTokens).toEqual([ { text: "hello", position: 0 }, { text: "こんにちは", position: 1 }, { text: "世界", position: 2 }, ]);该测试揭示了两个关键事实:
- 分词结果与索引配置强相关:
simple分词器会做词干还原(Running→run、cafés→cafe),而icu分词器支持基于字典的日文分词(こんにちは世界被正确切分为こんにちは和世界)。 - position 记录的是分词序列中的位置:
in被simple分词器当作停用词移除后,cafe的 position 为 2,说明 position 基于分词后的序列而非原文词序。
五、与 FTS 索引分词器配置的对应关系
column或indexName指向的 FTS 索引,其分词器由创建索引时的FtsOptions配置决定。在 nodejs/lancedb/indices.ts 中,FtsOptions.baseTokenizer支持以下取值:
"simple":以空白和标点作为分隔符切分文本(默认值),通常配合词干还原与停用词过滤;"whitespace":仅以空白作为分隔符;"raw":不切分文本,将整段文本作为单个 token 索引;"ngram":按 n-gram 切分,可配合ngramMinLength、ngramMaxLength、prefixOnly使用;"icu":基于 ICU 字典的词分割;"icu/split":ICU 分割 + 简单式分隔符切分;`jieba/${string}`与`lindera/${string}`:基于模型的分词器(如中文分词)。
此外,FtsOptions还支持language(词干还原与停用词语言)、lowercase、stem、removeStopWords、customStopWords、maxTokenLength、asciiFolding等分词过滤配置。创建 FTS 索引示例:
await table.createIndex("text", { config: Index.fts({ baseTokenizer: "simple" }), }); await table.createIndex("japanese", { config: Index.fts({ baseTokenizer: "icu", stem: false, removeStopWords: false, }), name: "japanese_icu_idx", });这也解释了为什么tokenize()无需显式传入分词器类型——分词器配置已经固化在索引元数据中,TokenizeTableOptions只需定位到索引即可。
六、使用注意事项
- 模型型分词器的本地依赖:从
Table.tokenize()的文档注释(nodejs/lancedb/table.ts)可以确认,jieba/*和lindera/*这类模型型分词器会在客户端进程内根据索引元数据重建。对于远程表,意味着本地也必须存在相同的分词器模型文件,否则无法完成分词。 - 编译期与运行期双重约束:TS 类型层面通过
?: never保证二选一,运行时 Rust 层再次校验,二者共同保证参数使用的正确性。 - 先建索引再分词:
tokenize()依赖已存在的 FTS 索引获取分词器配置,因此调用前需确保目标列或索引名对应的 FTS 索引已通过createIndex创建。
相关资源
- 类型别名定义:nodejs/lancedb/table.ts
- 调用方方法签名与文档:nodejs/lancedb/table.ts
- 返回值类型
FtsToken:nodejs/lancedb/table.ts - Rust 侧实现与参数校验:nodejs/src/table.rs
- 测试用例:nodejs/test/table.test.ts
- FTS 索引与分词器配置:nodejs/lancedb/indices.ts
- 向量数据库
- 数据库
- 人工智能
- 后端
【免费下载链接】lancedb
Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.
相关推荐
LanceDB Node.js 全文检索分词:`tokenize()` 函数完全指南
LanceDB Node.js 全文检索分词: tokenize 函数完全指南 全文检索(Full Text Search, FTS)的效果高度依赖分词策略:同
向量数据库数据库人工智能后端LanceDB Node.js SDK 的 IntoSql 类型别名:类型安全的 SQL 字面量转换机制详解
LanceDB Node.js SDK 的 IntoSql 类型别名:类型安全的 SQL 字面量转换机制详解 导读 :本文围绕 LanceDB Node.js
向量数据库数据库人工智能后端LanceDB Node.js 全文检索分词配置:TokenizeOptions 接口完全指南
LanceDB Node.js 全文检索分词配置:TokenizeOptions 接口完全指南 导读 本文聚焦 LanceDB Node.js 客户端中 Tok
向量数据库数据库人工智能后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考