跳到主要内容

rxdb-plugin-search

@aiao/rxdb 的全局搜索插件。为标注 searchable: true 字段的 collection 提供响应式全文检索,SQLite 走 FTS5,PGlite 走 tsvector / GIN。

适配器支持面由 backend-registry.ts 登记表决定:sqlite-wasm / sqlite / sqliteai / pglite 为 supported; wa-sqlite 与小程序为 unverified(实验性,npm 预编译 wasm 未编入 FTS5),与未登记的适配器一样在 createRxDatabase 阶段抛 SearchUnsupportedAdapterError,不降级。

安装​

pnpm add @aiao/rxdb @aiao/rxdb-plugin-search @aiao/rxdb-adapter-sqlite-wasm rxjs

用法​

import { firstValueFrom } from 'rxjs';
import { rxDBPluginSearch } from '@aiao/rxdb-plugin-search';

db.use(rxDBPluginSearch, {
debounce: 300,
pageSize: 50,
snippetLength: 120
});

// connect() 会同步触发 init(),插件随后完成 FTS 安装与回填。
await db.connect('sqlite-wasm');
await db.searchPlugin.ready;

const handle = db.search('local first', { collections: ['Article'] });
const results = await firstValueFrom(handle.results$);

handle.destroy();
await db.disconnect('sqlite-wasm');

db.searchPlugin.ready 一个连接纪元一格:connect() 之前与安装期间是 pending,安装成功 resolve、失败 reject(原始错误),纪元被释放(断连 / 回滚)后 reject destroyed。可以在 connect() 之前就拿到它的引用——那一格会被本纪元的安装续用;但跨断连持有同一个引用读到的 是那一纪元的结果,重连之后要重新读一次。

db.search() 返回的 SearchHandle 由调用方负责 destroy();Angular、React、Vue 绑定会在组件 生命周期结束时自动销毁。

连接纪元​

插件声明 inject: ['adapter:local'],由宿主决定装载时机:本地适配器的引导链跑完之后才调 install(),插件自己不再等连接信号。因此 await db.connect() 返回时 FTS 已经装好—— ready 是给「装了没有 / 装失败了没有」的显式确认,不是必须的等待点。

entity 事件监听与状态复位都登记在 install(scope) 收到的作用域上。插件声明了 lifecycle: 'scoped',宿主释放作用域即完成拆卸,没有第二步 destroy()。插件身份 db.searchPlugin 跨纪元存活,重新 connect() 会复用同一实例并重新安装 FTS。

框架绑定:Angular 用 @aiao/rxdb-plugin-search-angular,React 用 @aiao/rxdb-plugin-search-react,Vue 用 @aiao/rxdb-plugin-search-vue。

文档​

License​

MIT

rxdb-plugin-search - RxDB 全局搜索插件

为标注 searchable: true 字段的 collection 提供响应式全文检索。

Remarks​

具体的全文引擎由当前 adapter 决定,见 SEARCH_BACKEND_DESCRIPTORS: SQLite 家族(sqlite-wasm / sqlite / sqliteai)走 FTS5 外部内容虚拟表, pglite 走 PostgreSQL 物化 tsvector 列 + GIN 索引。 未登记或登记为待实测的 adapter 会在数据库创建阶段 fail-fast,错误里带可判别的原因。

Classes​

ClassDescription
RxDBPluginSearch@aiao/rxdb-plugin-search 主类。
SearchBackendCapabilityErroradapter 名解析出的后端正确,但活连接缺少该后端必需的存储能力。
SearchEncryptedFieldError一个字段同时声明 encrypted: true 与 searchable: true。
SearchError@aiao/rxdb-plugin-search 错误基类。
SearchExecutionError运行时执行错误(SQL 失败 / 存储不可用);可通过 SearchHandle.retry 恢复。
SearchQueryLimitError运行时执行错误(SQL 失败 / 存储不可用);可通过 SearchHandle.retry 恢复。
SearchSchemaMismatchErrorFTS5 迁移签名与当前 schema 冲突;启动即抛,阻止挂载。
SearchUnsupportedAdapterError当前数据库的 adapter 无法映射到任何一种搜索后端;在 createRxDatabase 阶段 fail-fast, 插件不挂载 .search,不返回降级 Handle。

Interfaces​

InterfaceDescription
CreateSearchHandleOptionsSearchHandle 工厂配置。
FtsInstallPlan单个 entity 的 FTS5 安装计划
InstallFtsResult单个 entity 的安装结果。
InvalidSearchableFieldSchema 校验失败详情。
MigrationRecordStore迁移记录访问抽象。插件不直接依赖 RxDBMigration entity,方便单测与复用。
ResolveScopeInput解析参与聚合的 collection 范围。
RuntimeSqlExecutor原子 SQL 执行接口。与 @aiao/rxdb-adapter-sqlite-core 的 RxDBAdapterSqliteBase.rawQuery 形状一致。
SearchBackend一种全文搜索后端的完整实现。
SearchBackendCapabilities后端自我声明的能力集合。
SearchBackendDescriptor单个 adapter 的登记项。
SearchEngine由 createSearchEngine(...) 返回的 engine 句柄。
SearchEngineQuerycreateSearchEngine().search(...) 入参。
SearchHandle由 collection.search() / rxDB.search() 返回的响应式句柄。
SearchOptions单次搜索请求的可调参数;可覆盖 SearchPluginOptions 全局默认。
SearchPage单页查询结果 + 是否还有下一页。
SearchPluginOptionsrxDBPluginSearch(options) 的初始化选项。
SearchResult单条搜索命中。
SearchSourceLike暴露 search() 方法的最小数据源形状(RxDB / RxCollection)。
SearchStateSnapshot状态机内部快照(包含所有可观察派生字段)。

Type Aliases​

Type AliasDescription
FtsExecutorSQL 执行适配器:接受参数化 SQL 返回 FTS 行。
PerformSearch由 plugin.ts 注入的"真正干活"函数:给定查询词与页号,返回该页结果。
SearchBackendId已实现的搜索后端标识。
SearchBackendStatus登记状态。
SearchQueryLimitKind查询编译预算超限;不会执行 SQL,可通过 error$ 观察并由调用方提示用户缩短输入。
SearchStateSearchHandle 状态机五态。
SearchStateMachinecreateSearchState 的返回值类型;可在 SearchHandle 实现中按结构引用。

Variables​

VariableDescription
FULL_SEARCH_CAPABILITIES两套后端当前均已实现全部能力;抽成常量避免各自重复字面量导致漂移。
MAX_CONTAINS_FALLBACK_ROWS超过此源表行数时不执行无索引的 contains fallback。
MAX_QUERY_LENGTH原始查询最大 UTF-16 code unit 数,限制编译和 FTS 表达式的内存增长。
MAX_QUERY_TOKENS单次查询最多保留的 token 数,远低于 SQLite bind / expression 硬上限。
MAX_TOKEN_LENGTH单个 token 最大 UTF-16 code unit 数,避免超长 phrase 压垮 FTS tokenizer。
rxDBPluginSearch插件工厂;与 rxDBPluginTrigger 等同形态。
SEARCH_BACKEND_DESCRIPTORS全部登记项。
SEARCHABLE_PROPERTY_TYPES-

Functions​

FunctionDescription
assertSearchableSchemaValid汇总式校验:遇到任何非法字段即抛错,否则静默通过。
buildBackfillSql回填 SQL:外部内容 FTS5 表用 rowid 绑定主键;stringArray 字段走 json_each 子查询。
buildFieldContainsSql单字段 contains fallback SQL。
buildFieldMatchExpressionFTS5 列过滤表达式:<field> : (<compiled.match>)
buildFieldSearchSql单字段搜索 SQL。
buildResetFtsSqlFTS5 虚拟表 reset 命令:清空索引但保留表结构。
buildSourceRowCountSqlcontains fallback 前的行数预算探针。
collectInvalidSearchableFields扫描 entity metadata 中所有被显式标注 searchable: true 的字段, 收集类型不合法(非 string/enum/stringArray)的条目。
createFts5Backend构造 SQLite FTS5 后端。
createPgTsvectorBackend构造 PostgreSQL tsvector 后端。
createSearchBackend按后端标识构造后端实例。
createSearchEngine构造一个 SearchEngine,绑定 SQL 执行器。
createSearchHandle组装 SearchHandle。调用方只需关心状态流与生命周期管理。
createSearchState创建一个全新的搜索状态机。
installFtsForEntity执行单个 entity 的 FTS5 安装;幂等。
lookupSearchBackendDescriptor查登记项。
resolveSearchBackend解析当前 adapter 对应的搜索后端;不可用即抛。
resolveSearchScope计算最终参与搜索聚合的 collection 名列表(保持与 candidates 同序、去重)。
searchOptionsEqual判断两份 SearchOptions 在重建 SearchHandle 的意义上是否等价。