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

在IndexedDB中使用复合索引时如何查询单列数据

问题描述

我有一个IndexedDB数据库,其中包含基于['name', 'surname']两个字段的复合索引。如何查询所有name=='Will'的行?

ChatGPT给出了如下示例代码,但无法正常工作(返回空数组):

const getDb = async () =>
  await openDB("myDB", 1, {
    upgrade(db, _oldVersion, _newVersion, _transaction) {
      var roleStore = db.createObjectStore("myStore", {autoIncrement: true});
      roleStore.createIndex('compoundIndex', ['name', 'surname'], {
        unique: true,
      });
    },
  });

const fetchName = async(name) => {
  const db = await getDb();
  return await db
      .transaction("myStore", 'readonly')
      .objectStore("myStore")
      .index('compoundIndex')
      .getAll(IDBKeyRange.only([name, '']));
}

console.log(fetchName("Will")); // Returns empty array!

是否存在无需获取所有值再使用JS的.filter()函数,就能查询所有匹配name=='Will'行的简便方法?


解决方案

问题根源

原代码使用IDBKeyRange.only([name, '']),这只会精确匹配name为Will且surname为空字符串的条目,自然无法返回其他surname不为空的Will相关数据。

正确实现

利用复合索引的排序特性,使用IDBKeyRange.bound构造范围查询:起始键设为[name, ''],结束键设为[name, '\uffff'](\uffff是Unicode编码中的最大字符,能覆盖所有可能的surname值),这样就能匹配所有name为目标值的条目。

修正后的查询函数如下:

const fetchName = async(name) => {
  const db = await getDb();
  // 构造匹配所有name为目标值的键范围
  const range = IDBKeyRange.bound(
    [name, ''],
    [name, '\uffff'],
    false, // 不排除起始键
    false  // 不排除结束键
  );
  return await db
      .transaction("myStore", 'readonly')
      .objectStore("myStore")
      .index('compoundIndex')
      .getAll(range);
}

验证示例(可选)

若要验证功能,可添加插入测试数据的函数:

const insertData = async(data) => {
  const db = await getDb();
  const tx = db.transaction("myStore", 'readwrite');
  await tx.objectStore("myStore").add(data);
  await tx.done;
}

// 插入测试数据
await insertData({name: 'Will', surname: 'Smith'});
await insertData({name: 'Will', surname: 'Johnson'});
await insertData({name: 'John', surname: 'Doe'});

// 查询验证
console.log(await fetchName("Will")); // 返回两条Will相关的数据

内容的提问来源于stack exchange,提问作者Ander

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:22:53