Signatur
Beschreibung
IDBKeyRange.lowerBound() erzeugt einen Schlüsselbereich, der nach unten begrenzt und nach oben offen ist. Damit lassen sich in IndexedDB alle Datensätze abfragen, deren Schlüssel (oder Indexwert) größer oder gleich bzw. strikt größer als ein bestimmter Wert ist – etwa „alle Bestellungen ab dem 1. Januar“ oder „alle Nutzer mit einer ID größer als 100“.
Der erzeugte Bereich wird an Methoden wie IDBObjectStore.getAll(), IDBIndex.openCursor(), count() oder delete() übergeben. Mit dem zweiten Parameter open legst du fest, ob der Grenzwert selbst eingeschlossen (false, Standard) oder ausgeschlossen (true) wird.
Die Sortierung folgt den IndexedDB-Regeln für Schlüsselvergleiche: Zahlen < Datumswerte < Strings < Binärdaten < Arrays. Ein Bereich mit einer Zahl als untere Grenze umfasst daher auch alle Strings, Datumswerte und Arrays – wichtig, wenn ein Store gemischte Schlüsseltypen enthält.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $lower Pflicht | number | string | Date | ArrayBuffer | ArrayBufferView | Array | Die untere Grenze des Bereichs. Muss ein gültiger IndexedDB-Schlüssel sein. | |
| $open | boolean | false | Bei true wird der Grenzwert selbst ausgeschlossen (>), bei false eingeschlossen (>=). |
Beispiele
Eigenschaften eines Bereichs prüfen
const inklusiv = IDBKeyRange.lowerBound(10);
const exklusiv = IDBKeyRange.lowerBound(10, true);
console.log(inklusiv.lower, inklusiv.lowerOpen, inklusiv.upper);
console.log(exklusiv.includes(10), exklusiv.includes(11));
Alle Bestellungen ab einem Datum laden
const getOrdersSince = (db, since) =>
new Promise((resolve, reject) => {
const tx = db.transaction('orders', 'readonly');
const index = tx.objectStore('orders').index('createdAt');
const request = index.getAll(IDBKeyRange.lowerBound(since));
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
const open = indexedDB.open('shop', 1);
open.onupgradeneeded = () => {
const store = open.result.createObjectStore('orders', { keyPath: 'id' });
store.createIndex('createdAt', 'createdAt');
};
open.onsuccess = async () => {
const orders = await getOrdersSince(open.result, new Date('2024-01-01'));
console.log(`${orders.length} Bestellungen seit Jahresbeginn`);
};
Cursor-Paginierung: nächste Seite nach der letzten ID
const loadNextPage = (db, lastId, pageSize = 20) =>
new Promise((resolve, reject) => {
const store = db.transaction('users').objectStore('users');
// open = true: die letzte bereits geladene ID nicht erneut liefern
const range = lastId == null ? null : IDBKeyRange.lowerBound(lastId, true);
const request = store.getAll(range, pageSize);
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
// Wichtig · Fallstricke
- Ist
lowerkein gültiger Schlüssel (z. B.null,undefined, ein Objekt,NaNoder ein ungültigesDate), wirft die Methode eineDOMExceptionvom TypDataError. - Boolesche Werte sind keine gültigen Schlüssel –
lowerBound(true)schlägt fehl. - Gemischte Schlüsseltypen:
lowerBound(0)umfasst auch alle Strings und Datumswerte, weil diese in der IndexedDB-Sortierung nach Zahlen kommen. Bei Bedarf zusätzlich mitIDBKeyRange.bound()nach oben begrenzen. - Für absteigende Abfragen kombinierst du den Bereich mit
openCursor(range, 'prev'). - Kompatibilität: in allen modernen Browsern und Web Workern verfügbar; im privaten Modus einiger älterer Browser war IndexedDB eingeschränkt.