IndexedDB - Searching
IndexedDB: Searching and Querying Data
Section titled “IndexedDB: Searching and Querying Data”As a structured database, IndexedDB provides efficient mechanisms for searching and retrieving data. You can query records based on their primary key or by using indexes for more complex lookups on other properties of your objects.
Searching by Primary Key
Section titled “Searching by Primary Key”The most direct way to retrieve data is by its primary key using the get() method. For more advanced queries, you can use an IDBKeyRange object to specify a range of keys.
The primary methods for key-based searching are:
store.get(key): Search for the first value that matches the key.store.getAll([query], [count]): Search for all values matching the optional query (a key or a key range), up to acountlimit.store.getKey(key): Search for the first key that matches the key.store.getAllKeys([query], [count]): Search for all keys matching the optional query, up to acountlimit.store.count([query]): Get the total count of records matching the optional query.
Example: Querying by Key and Range
Section titled “Example: Querying by Key and Range”// Assuming 'db' is an open IDBDatabase instance from the 'idb' library
// Get a single product by its ID (primary key)const product = await db.get('products', 'prod-123');
// Get all products with IDs between 'prod-100' and 'prod-200'const keyRange = IDBKeyRange.bound('prod-100', 'prod-200');const products = await db.getAll('products', keyRange);
// Get the first 5 product keys onlyconst keys = await db.getAllKeys('products', null, 5);Searching with Indexes
Section titled “Searching with Indexes”To efficiently search by a property other than the primary key, you must create an index. An index maintains a sorted list of references to your objects based on a specified property, allowing for fast lookups.
Indexes can only be created within the upgrade callback of openDB.
Syntax: objectStore.createIndex()
Section titled “Syntax: objectStore.createIndex()”objectStore.createIndex(indexName, keyPath, [options]);indexName: A unique name for the index.keyPath: The property path of the object to index (e.g.,'price'or'address.city').options: An optional object with configuration properties:
unique: true: Ensures that no two records in the store can have the same value for this index key. An attempt to add a duplicate will cause an error.
multiEntry: true: If the keyPath resolves to an array, the index will add an entry for each member of the array. This is perfect for implementing tags or categories.
Example: Creating an Index
Section titled “Example: Creating an Index”// Inside the 'upgrade' callbackconst productsStore = db.createObjectStore('products', { keyPath: 'id' });
// Create an index to search products by their 'category'productsStore.createIndex('categoryIdx', 'category', { unique: false });
// Create an index for tags using multiEntryproductsStore.createIndex('tagsIdx', 'tags', { multiEntry: true });Complete Search Example
Section titled “Complete Search Example”This example demonstrates setting up a database with a ‘products’ store and a ‘category’ index, adding data, and then searching for all products in the ‘electronics’ category.
<!DOCTYPE html><html lang="en"><head> <title>IndexedDB Search Example</title></head><body> <h1>Check the console for output</h1> <script type="module"> import { openDB } from 'https://cdn.jsdelivr.net/npm/idb@7/build/index.js';
async function runDemo() { const db = await openDB('shopDB', 1, { upgrade(db) { if (!db.objectStoreNames.contains('products')) { const store = db.createObjectStore('products', { keyPath: 'id' }); store.createIndex('categoryIdx', 'category'); } }, });
const tx = db.transaction('products', 'readwrite'); const store = tx.objectStore('products');
// Add some sample data await Promise.all([ store.put({ id: 'p1', name: 'Laptop', category: 'electronics' }), store.put({ id: 'p2', name: 'T-Shirt', category: 'apparel' }), store.put({ id: 'p3', name: 'Keyboard', category: 'electronics' }), ]);
await tx.done; console.log('Database populated!');
// Now, search for all 'electronics' products using the index const electronics = await db.getAllFromIndex('products', 'categoryIdx', 'electronics');
console.log('Electronics Products:', electronics); console.table(electronics); }
runDemo().catch(console.error); </script></body></html>Expected Output (in browser console)
Section titled “Expected Output (in browser console)”Database populated!Electronics Products: [ { id: 'p1', name: 'Laptop', category: 'electronics' }, { id: 'p3', name: 'Keyboard', category: 'electronics' } ]
(console.table output)┌─────────┬──────┬───────────┬───────────────┐│ (index) │ id │ name │ category │├─────────┼──────┼───────────┼───────────────┤│ 0 │ 'p1' │ 'Laptop' │ 'electronics' ││ 1 │ 'p3' │ 'Keyboard'│ 'electronics' │└─────────┴──────┴───────────┴───────────────┘