You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:22:41