IndexedDBでデータをまとめて取得するには?
IndexedDBはWebブラウザ上で使えるJSONをサポートしたKVSです。KVSなのでデータの取得はキー単位なのですが、それだとキーを知らないとデータにアクセスできなくなりますので若干不便です。
そこで使えるのがカーソルとインデックスになります。
カーソルの使い方
カーソルはオブジェクトストアに対して openCursor メソッドで実行します。まず IndexedDB を開きます。
| let db; | |
| let version = 1; | |
| const request = indexedDB.open("database", version); | |
| request.onerror = function(event) { | |
| alert("IndexedDB が使えません"); | |
| }; | |
| request.onsuccess = function(event) { | |
| db = event.target.result; | |
| } |
次にトランザクションを開き、オブジェクトストアに対して openCursor メソッドを実行します。 データはイテレーションになっており、 continue メソッドで次のデータを取得します。
| const transaction = db.transaction(["items"]); | |
| const objItem = transaction.objectStore("items"); | |
| objItem.openCursor().onsuccess = function(event) { | |
| const row = event.target.result; | |
| if (row) { | |
| console.log(row.value); | |
| row.continue(); | |
| } | |
| } |
すべてのデータを取得する getAll
IndexedDB2 からは全データをまとめて取得する getAll メソッドが追加されました。こちらはイテレーションではなく、すべてのデータが配列になって取得できます。大量のデータではない時にはこちらのが簡単でしょう。同じようにキーだけを取得できる getAllKeys メソッドも用意されています。
| const transaction = db.transaction(["items"]); | |
| const objItem = transaction.objectStore("items"); | |
| objItem.getAll().onsuccess = function(event) { | |
| const rows = event.target.result; | |
| console.log(rows); | |
| } |
インデックスを使う
データに対してインデックスを設けている場合には、それを使ってデータを指定できます。データがnameをキーにして昇順で取得できます(0が最初)。
| const transaction = db.transaction(["items"]); | |
| const objItem = transaction.objectStore("items"); | |
| const Index = objItem.index('name'); | |
| Index.openCursor().onsuccess = function(event) { | |
| const row = event.target.result; | |
| if (row) { | |
| console.log(row.value); | |
| row.continue(); | |
| } | |
| } |
こちらもまた、getAllや getAllKeysが使えます。
まとめ
IndexedDBはあくまでもWebブラウザ内で使う軽量なデータベースになりますので、大量のデータを保存していることはほとんどないでしょう。そのため、openCursorを使って全データを取得したとしても遅くなるようなことはないかと思います。
なお、getAll や getAllKeysはIndexedDB2 からになり、執筆時点ではEdgeは未対応になります。
コメントは受け付けていません。