Start · Sprachen · JavaScript · Referenz · IDBKeyRange.bound()

IDBKeyRange.bound()

Methode

Erstellt ein <code>IDBKeyRange</code> mit unterer und oberer Grenze, wahlweise einschließend oder ausschließend, für Abfragen auf Object Stores und Indizes.

seit JavaScript Baseline: alle Browser (IndexedDB 2.0) Kategorie: webapi

Signatur

IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen)

Beschreibung

Die statische Methode IDBKeyRange.bound() erzeugt einen Schlüsselbereich mit einer unteren und einer oberen Grenze. Damit fragt man in IndexedDB gezielt Datensätze ab, deren Schlüssel (oder Indexwert) in einem bestimmten Intervall liegt, zum Beispiel alle Bestellungen zwischen zwei Datumswerten oder alle Namen, die mit einem bestimmten Präfix beginnen.

Standardmäßig gehören beide Grenzen zum Bereich (geschlossenes Intervall [lower, upper]). Über lowerOpen und upperOpen lässt sich jede Grenze einzeln ausschließen, also z. B. (lower, upper] oder [lower, upper).

Den erzeugten Bereich übergibt man an Methoden wie IDBObjectStore.getAll(), IDBIndex.openCursor(), count(), delete() oder getAllKeys(). Verglichen wird nach den IndexedDB-Schlüsselregeln: Zahlen < Datumswerte < Strings < Binärdaten < Arrays. Strings werden dabei nach Code-Einheiten verglichen, nicht nach Sprache.

Parameter

Name Typ Default Beschreibung
$lower Pflicht number|string|Date|ArrayBuffer|ArrayBufferView|Array Untere Grenze des Bereichs. Muss ein gültiger IndexedDB-Schlüssel sein.
$upper Pflicht number|string|Date|ArrayBuffer|ArrayBufferView|Array Obere Grenze des Bereichs. Muss ein gültiger Schlüssel sein und darf nicht kleiner als lower sein.
$lowerOpen boolean false Bei true wird die untere Grenze aus dem Bereich ausgeschlossen.
$upperOpen boolean false Bei true wird die obere Grenze aus dem Bereich ausgeschlossen.

Rückgabewert

Typ
IDBKeyRange
Beschreibung
Ein neues IDBKeyRange-Objekt mit den Eigenschaften lower, upper, lowerOpen und upperOpen.

Beispiele

Bereich erzeugen und inspizieren

const range = IDBKeyRange.bound(10, 20, false, true);
console.log(range.lower, range.upper, range.lowerOpen, range.upperOpen);
console.log(range.includes(10), range.includes(20));
10 20 false true true false

Bestellungen in einem Datumsbereich laden

const openDb = () => new Promise((resolve, reject) => {
  const req = indexedDB.open('shop', 1);
  req.onupgradeneeded = () => {
    const store = req.result.createObjectStore('orders', { keyPath: 'id', autoIncrement: true });
    store.createIndex('byDate', 'date');
  };
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const ordersInMonth = async (year, month) => {
  const db = await openDb();
  const start = new Date(year, month - 1, 1);
  const end = new Date(year, month, 1);
  // [start, end) – Monatsende exklusiv
  const range = IDBKeyRange.bound(start, end, false, true);
  return new Promise((resolve, reject) => {
    const req = db.transaction('orders').objectStore('orders')
      .index('byDate').getAll(range);
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
};

ordersInMonth(2024, 3).then((orders) => console.log(orders.length, 'Bestellungen im März'));
z. B.: 42 Bestellungen im März

Präfixsuche mit Cursor

const findByPrefix = (db, prefix) => new Promise((resolve, reject) => {
  // '\uffff' als obere Grenze deckt alle Strings mit diesem Präfix ab
  const range = IDBKeyRange.bound(prefix, prefix + '\uffff');
  const results = [];
  const req = db.transaction('users').objectStore('users')
    .index('byName').openCursor(range);
  req.onsuccess = () => {
    const cursor = req.result;
    if (cursor) {
      results.push(cursor.value.name);
      cursor.continue();
    } else {
      resolve(results);
    }
  };
  req.onerror = () => reject(req.error);
});

// Aufruf: findByPrefix(db, 'Mei').then(console.log);
z. B.: ["Meier", "Meissner", "Meiwes"]

// Wichtig · Fallstricke

  • DataError: Die Methode wirft eine DOMException namens DataError, wenn lower oder upper kein gültiger Schlüssel ist (z. B. undefined, null, Objekt, NaN, ungültiges Date), wenn lower > upper ist oder wenn beide Grenzen gleich sind und mindestens eine offen ist.
  • Für einen einzelnen Schlüssel besser IDBKeyRange.only() verwenden, für einseitig offene Bereiche lowerBound() oder upperBound().
  • Datumsbereiche am besten halboffen (upperOpen = true) mit dem Beginn des Folgetags angeben, dann gibt es keine Probleme mit Uhrzeiten wie 23:59:59.999.
  • Strings werden nach Code-Einheiten verglichen: Großbuchstaben kommen vor Kleinbuchstaben, Umlaute hinter z. Für eine Suche ohne Unterscheidung von Groß- und Kleinschreibung sollte man einen normalisierten Indexwert speichern.
  • Browser-Kompatibilität: IndexedDB wird von allen modernen Browsern unterstützt. In Web Workern ist die Methode ebenfalls verfügbar. In privaten Fenstern kann IndexedDB eingeschränkt sein.