前回からのつづき
前回、IndexedDBのオブジェクトを中心にAPIの説明を行ってきましたが、今回は、その続きとなります。
検索の要となる IDBKeyRangeオブジェクトの使い方を中心に、検索方法ついて説明します。
IDBKeyRangeとは?
IndexedDBの検索を支える超重要API
■ 結論(最初にここだけ読めばOK)
IDBKeyRange は
👉 **「どのデータを取得するかを決める条件オブジェクト」**です。
SQLでいうと:
WHERE 条件
に相当します。
IDBKeyRangeとは何か?
IndexedDBにはSQLのような検索構文がありません。
その代わりに使うのが:
- IDBKeyRange(検索条件)
- Index(検索対象)
- Cursor(走査)
👉 この3つの組み合わせで検索を実現します
使い方(基本)
例えば「キーが10〜20のデータを取得」:
store.getAll(IDBKeyRange.bound(10, 20));
IDBKeyRangeの作り方(4種類)
① only(一致検索)
IDBKeyRange.only(value)
例:
IDBKeyRange.only(5)
👉 キーが5のデータだけ取得
② lowerBound(下限)
IDBKeyRange.lowerBound(value, open)
例:
IDBKeyRange.lowerBound(10)
👉 10以上
open の意味
- false(デフォルト) → 10以上(>=)
- true → 10より大きい(>)
③ upperBound(上限)
IDBKeyRange.upperBound(value, open)
👉 value以下
④ bound(範囲検索)
IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen)
👉 最もよく使う
例:
IDBKeyRange.bound(10, 20)
👉 10以上20以下
図で理解する
only(5)
→ [5]
lowerBound(10)
→ [10 -------->
upperBound(20)
→ <-------- 20]
bound(10,20)
→ [10 ----- 20]
どこで使うのか?
① get / getAll
store.getAll(IDBKeyRange.bound(10, 20));
② Cursor(本命)
store.openCursor(IDBKeyRange.lowerBound(100));
👉 100以上だけ順に処理
③ Indexと組み合わせ
store.index("age")
.openCursor(IDBKeyRange.bound(20, 30));
👉 年齢20〜30のデータだけ取得
実務でよく使うパターン
① ページング処理
IDBKeyRange.lowerBound(lastKey, true)
👉 前回の続きから取得
② 日付範囲検索
IDBKeyRange.bound(
new Date("2024-01-01"),
new Date("2024-12-31")
)
③ 前方一致検索(テクニック)
IDBKeyRange.bound("abc", "abc\uffff")
👉 "abc〜" で始まるデータ
なぜ重要なのか?
👉 IndexedDBにはWHERE句がない
SQLのように:
SELECT * WHERE age > 20
とは書けません。
👉 代わりにこうする
store.index("age")
.openCursor(IDBKeyRange.lowerBound(20));
👉 必要なデータ("age"が20以上のもの)だけ取得できる
よくあるNG例
❌ 全件取得してフィルタ
// 非効率(絶対NGに近い)
const all = await store.getAll();
const result = all.filter(x => x.age > 20);
👉 大量データで詰む
✔ 正しいやり方
store.index("age")
.openCursor(IDBKeyRange.lowerBound(20));
👉 取得する対照データを絞り込む
注意点(ハマりやすい)
❗ キーにしか使えない
👉 valueの中身では検索できない → Indexが必要
❗ 型が一致していないとヒットしない
"10" !== 10
❗ 無効な値はエラー
IDBKeyRange.only(undefined) // NG
IDBKeyRangeの内部動作(少しだけ)
実は内部では:
👉 IndexedDBのキー比較ルールで判定されています
イメージ:
cmp(key, lower) >= 0 && cmp(key, upper) <= 0
まとめ
✔ IDBKeyRangeとは
👉 「どのキーを対象にするか決める条件オブジェクト」
✔ よく使うもの
- only(一致)
- bound(範囲)
- lowerBound(ページング)
✔ 本質
👉 IndexedDBの検索そのもの。一言でいうと「IndexedDBのWHERE句」
ここを理解すると、IndexedDBが「使いにくい」から 👉「自由に扱えるDB」に変わります 👍
(つづく)