Angular 11中用Dexie.js操作IndexedDB实现中间匹配搜索遇错求助
Angular 11 + Dexie.js 实现 IndexedDB 模糊搜索方案
先解决 db.transaction(...).objectStore is not a function 报错
你错误混用了原生 IndexedDB 的 API 语法,Dexie.js 对 transaction 做了封装,返回的是包含目标表的对象,不能直接调用 objectStore(),改用 .table() 获取表即可。
基础模糊搜索实现(小数据量适用)
如果你的数据量不大(比如几百条以内),直接全表读取后过滤是最简单的方案:
1. 定义 Dexie 数据库
import Dexie from 'dexie'; class UserDB extends Dexie { users: Dexie.Table<{id?: number, email: string, full_name: string}, number>; constructor() { super('UserDatabase'); this.version(1).stores({ users: '++id, email, full_name' }); this.users = this.table('users'); } } const db = new UserDB();
2. 实现模糊搜索函数
async function searchUsers(keyword: string): Promise<{id: number, email: string, full_name: string}[]> { try { return await db.transaction('r', db.users, async () => { const allUsers = await db.users.toArray(); // 匹配 email 或 full_name 任意位置包含关键词的记录(忽略大小写) return allUsers.filter(user => user.email.toLowerCase().includes(keyword.toLowerCase()) || user.full_name.toLowerCase().includes(keyword.toLowerCase()) ); }); } catch (err) { console.error('搜索失败:', err); return []; } }
大数据量优化方案
如果数据量上千条,全表过滤会有性能瓶颈,推荐以下两种方案:
方案一:预建多值索引(自定义 Token)
通过预生成搜索 Token,利用 Dexie 的多值索引实现高效查询:
1. 更新数据库 Schema
class UserDB extends Dexie { users: Dexie.Table<{id?: number, email: string, full_name: string, search_tokens: string[]}, number>; constructor() { super('UserDatabase'); this.version(2).stores({ users: '++id, email, full_name, *search_tokens' // * 表示多值索引 }); this.users = this.table('users'); } }
2. 生成搜索 Token
为每个用户的 email 和 full_name 生成所有可能的子串前缀,存入 search_tokens:
function generateSearchTokens(...fields: string[]): string[] { const tokens = new Set<string>(); fields.forEach(field => { if (!field) return; const lowerField = field.toLowerCase(); for (let i = 0; i < lowerField.length; i++) { tokens.add(lowerField.slice(i)); } }); return Array.from(tokens); } // 新增用户时自动生成 Token async function addUser(user: {email: string, full_name: string}) { user.search_tokens = generateSearchTokens(user.email, user.full_name); await db.users.add(user); }
3. 高效搜索
async function optimizedSearch(keyword: string): Promise<{id: number, email: string, full_name: string}[]> { const lowerKeyword = keyword.toLowerCase(); // 通过多值索引匹配包含关键词前缀的记录,distinct() 去重 return db.users.where('search_tokens').startsWith(lowerKeyword).distinct().toArray(); }
方案二:使用 Dexie 全文搜索插件
借助 dexie-fulltext-plugin 实现开箱即用的全文模糊搜索:
1. 安装插件
npm install dexie-fulltext-plugin
2. 配置数据库与搜索
import Dexie from 'dexie'; import 'dexie-fulltext-plugin'; class UserDB extends Dexie { users: Dexie.Table<{id?: number, email: string, full_name: string}, number>; constructor() { super('UserDatabase'); this.version(3).stores({ users: '++id, email, full_name' }); // 为 email 和 full_name 建立全文索引 this.users.createFullTextIndex('fullTextIndex', ['email', 'full_name']); this.users = this.table('users'); } } // 全文搜索 async function fullTextSearch(keyword: string): Promise<{id: number, email: string, full_name: string}[]> { return db.users.where('fullTextIndex').match(keyword).toArray(); }
内容的提问来源于stack exchange,提问作者Axel Blaz
相关产品推荐
相关产品推荐

