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。
文档
- 仓库主页:https://github.com/aiao-io/rxdb
- 插件指南见项目文档站
License
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
| Class | Description |
|---|---|
| RxDBPluginSearch | @aiao/rxdb-plugin-search 主类。 |
| SearchBackendCapabilityError | adapter 名解析出的后端正确,但活连接缺少该后端必需的存储能力。 |
| SearchEncryptedFieldError | 一个字段同时声明 encrypted: true 与 searchable: true。 |
| SearchError | @aiao/rxdb-plugin-search 错误基类。 |
| SearchExecutionError | 运行时执行错误(SQL 失败 / 存储不可用);可通过 SearchHandle.retry 恢复。 |
| SearchQueryLimitError | 运行时执行错误(SQL 失败 / 存储不可用);可通过 SearchHandle.retry 恢复。 |
| SearchSchemaMismatchError | FTS5 迁移签名与当前 schema 冲突;启动即抛,阻止挂载。 |
| SearchUnsupportedAdapterError | 当前数据库的 adapter 无法映射到任何一种搜索后端;在 createRxDatabase 阶段 fail-fast, 插件不挂载 .search,不返回降级 Handle。 |
Interfaces
| Interface | Description |
|---|---|
| CreateSearchHandleOptions | SearchHandle 工厂配置。 |
| FtsInstallPlan | 单个 entity 的 FTS5 安装计划 |
| InstallFtsResult | 单个 entity 的安装结果。 |
| InvalidSearchableField | Schema 校验失败详情。 |
| MigrationRecordStore | 迁移记录访问抽象。插件不直接依赖 RxDBMigration entity,方便单测与复用。 |
| ResolveScopeInput | 解析参与聚合的 collection 范围。 |
| RuntimeSqlExecutor | 原子 SQL 执行接口。与 @aiao/rxdb-adapter-sqlite-core 的 RxDBAdapterSqliteBase.rawQuery 形状一致。 |
| SearchBackend | 一种全文搜索后端的完整实现。 |
| SearchBackendCapabilities | 后端自我声明的能力集合。 |
| SearchBackendDescriptor | 单个 adapter 的登记项。 |
| SearchEngine | 由 createSearchEngine(...) 返回的 engine 句柄。 |
| SearchEngineQuery | createSearchEngine().search(...) 入参。 |
| SearchHandle | 由 collection.search() / rxDB.search() 返回的响应式句柄。 |
| SearchOptions | 单次搜索请求的可调参数;可覆盖 SearchPluginOptions 全局默认。 |
| SearchPage | 单页查询结果 + 是否还有下一页。 |
| SearchPluginOptions | rxDBPluginSearch(options) 的初始化选项。 |
| SearchResult | 单条搜索命中。 |
| SearchSourceLike | 暴露 search() 方法的最小数据源形状(RxDB / RxCollection)。 |
| SearchStateSnapshot | 状态机内部快照(包含所有可观察派生字段)。 |
Type Aliases
| Type Alias | Description |
|---|---|
| FtsExecutor | SQL 执行适配器:接受参数化 SQL 返回 FTS 行。 |
| PerformSearch | 由 plugin.ts 注入的"真正干活"函数:给定查询词与页号,返回该页结果。 |
| SearchBackendId | 已实现的搜索后端标识。 |
| SearchBackendStatus | 登记状态。 |
| SearchQueryLimitKind | 查询编译预算超限;不会执行 SQL,可通过 error$ 观察并由调用方提示用户缩短输入。 |
| SearchState | SearchHandle 状态机五态。 |
| SearchStateMachine | createSearchState 的返回值类型;可在 SearchHandle 实现中按结构引用。 |
Variables
| Variable | Description |
|---|---|
| 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
| Function | Description |
|---|---|
| assertSearchableSchemaValid | 汇总式校验:遇到任何非法字段即抛错,否则静默通过。 |
| buildBackfillSql | 回填 SQL:外部内容 FTS5 表用 rowid 绑定主键;stringArray 字段走 json_each 子查询。 |
| buildFieldContainsSql | 单字段 contains fallback SQL。 |
| buildFieldMatchExpression | FTS5 列过滤表达式:<field> : (<compiled.match>) |
| buildFieldSearchSql | 单字段搜索 SQL。 |
| buildResetFtsSql | FTS5 虚拟表 reset 命令:清空索引但保留表结构。 |
| buildSourceRowCountSql | contains 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 的意义上是否等价。 |