Signatur
Beschreibung
Die Eigenschaft IDBCursor.primaryKey gibt den effektiven Primärschlüssel des aktuellen Datensatzes zurück. Das ist der Schlüssel, unter dem der Datensatz im Object Store gespeichert ist, entweder über den keyPath oder als automatisch erzeugter Schlüssel (autoIncrement).
Richtig nützlich wird die Eigenschaft bei Cursorn, die über einen Index laufen (IDBIndex.openCursor() bzw. openKeyCursor()). Dort enthält cursor.key den Index-Schlüssel, zum Beispiel eine E-Mail-Adresse oder ein Datum. cursor.primaryKey enthält dagegen den Primärschlüssel des zugehörigen Datensatzes im Object Store. Bei einem Cursor direkt auf einem Object Store sind key und primaryKey identisch.
Typische Einsätze sind: Datensätze gezielt über store.get(primaryKey) oder store.delete(primaryKey) ansprechen, Primärschlüssel über einen Key-Cursor ohne Laden der Werte einsammeln, oder mit IDBCursor.continuePrimaryKey() beim Blättern an einer bestimmten Stelle weitermachen.
Rückgabewert
Beispiele
Primärschlüssel über einen Object-Store-Cursor ausgeben
const request = indexedDB.open('shop', 1);
request.onupgradeneeded = () => {
const db = request.result;
const store = db.createObjectStore('produkte', { keyPath: 'id', autoIncrement: true });
store.add({ name: 'Tastatur' });
store.add({ name: 'Maus' });
};
request.onsuccess = () => {
const db = request.result;
const store = db.transaction('produkte').objectStore('produkte');
store.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return;
// Beim Store-Cursor sind key und primaryKey identisch
console.log(cursor.primaryKey, cursor.key, cursor.value.name);
cursor.continue();
};
};
Index-Cursor: Index-Schlüssel und Primärschlüssel unterscheiden
const db = await new Promise((resolve, reject) => {
const req = indexedDB.open('crm', 1);
req.onupgradeneeded = () => {
const store = req.result.createObjectStore('kunden', { keyPath: 'kundenNr' });
store.createIndex('nachStadt', 'stadt');
store.add({ kundenNr: 'K-100', stadt: 'Berlin' });
store.add({ kundenNr: 'K-200', stadt: 'Hamburg' });
store.add({ kundenNr: 'K-300', stadt: 'Berlin' });
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const index = db.transaction('kunden').objectStore('kunden').index('nachStadt');
index.openCursor().onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) return;
console.log(`Stadt: ${cursor.key} → Kunde: ${cursor.primaryKey}`);
cursor.continue();
};
Primärschlüssel per Key-Cursor sammeln und Datensätze löschen
// Löscht alle Kunden aus Berlin, ohne die Werte zu laden
const tx = db.transaction('kunden', 'readwrite');
const store = tx.objectStore('kunden');
const index = store.index('nachStadt');
const zuLoeschen = [];
index.openKeyCursor(IDBKeyRange.only('Berlin')).onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
zuLoeschen.push(cursor.primaryKey);
cursor.continue();
} else {
zuLoeschen.forEach((pk) => store.delete(pk));
console.log('Gelöscht:', zuLoeschen);
}
};
tx.oncomplete = () => console.log('Transaktion abgeschlossen');
// Wichtig · Fallstricke
- key und primaryKey verwechseln: Bei Index-Cursorn liefert
keyden Index-Wert und nicht den Primärschlüssel. Fürstore.get(),store.put()oderstore.delete()braucht manprimaryKey. - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird im nicht-strikten Modus stillschweigend ignoriert und löst im strikten Modus einen
TypeErroraus. - Der Wert gilt nur für die aktuelle Iteration. Nach
continue()oderadvance()ändert er sich. Den Wert sollte man deshalb sofort auslesen oder zwischenspeichern. - Hat der Cursor das Ende erreicht, ist
event.target.resultgleichnull. Dann gibt es auch keinenprimaryKey, deshalb vorher immer aufnullprüfen. - Zusammengesetzte Schlüssel (Arrays) und
Date-Objekte werden als neue Objekte zurückgegeben. Ein Vergleich mit===schlägt daher fehl; besser istindexedDB.cmp(a, b) === 0. - Kompatibilität: IndexedDB 1.0 wird in allen modernen Browsern unterstützt, auch in Web Workern. In manchen privaten Modi, zum Beispiel in älteren Firefox-Versionen, kann IndexedDB eingeschränkt sein.