Idb-keyval — это минималистичная обёртка над IndexedDB,
предназначенная для удобного хранения ключ-значение в браузере. Основной
фокус библиотеки — простота использования: операции get,
set, delete, clear и
keys позволяют манипулировать данными без глубокого
погружения в низкоуровневый API IndexedDB.
Для реализации поиска по значениям важно понимать, что стандартные методы Idb-keyval ориентированы на работу с ключами. Прямого метода поиска по значениям нет, поэтому необходимо комбинировать асинхронные операции для перебора данных и фильтрации по критериям.
Первый шаг при поиске по значениям — получить весь набор данных.
Idb-keyval предоставляет методы keys() и
get():
import { get, keys } from 'idb-keyval';
async function getAllEntries() {
const allKeys = await keys();
const entries = [];
for (const key of allKeys) {
const value = await get(key);
entries.push({ key, value });
}
return entries;
}
keys() возвращает массив всех ключей в хранилище.get(key) асинхронно получает значение для указанного
ключа.{ key, value }, с которым удобно работать дальше.Для поиска по конкретному критерию можно использовать стандартные
методы массива, например filter():
async function searchByValue(searchTerm) {
const entries = await getAllEntries();
return entries.filter(entry => {
// Предположим, что значения — строки или объекты с полем 'name'
if (typeof entry.value === 'string') {
return entry.value.includes(searchTerm);
} else if (entry.value && typeof entry.value.name === 'string') {
return entry.value.name.includes(searchTerm);
}
return false;
});
}
name объекта.При работе с большими хранилищами перебор всех ключей может быть дорогим по времени. Возможные оптимизации:
import { get, set } from 'idb-keyval';
async function addToIndex(key, value, indexKey = 'index') {
const index = (await get(indexKey)) || {};
index[key] = value.name || value;
await set(indexKey, index);
}
Поиск только по части данных Если известно, что значения имеют категориальный тип, можно хранить отдельные ключи для каждой категории и фильтровать только по ним.
Пакетное получение значений Вместо
последовательного await get(key) для каждого ключа можно
использовать Promise.all:
async function getAllEntriesParallel() {
const allKeys = await keys();
const values = await Promise.all(allKeys.map(key => get(key)));
return allKeys.map((key, i) => ({ key, value: values[i] }));
}
Это ускоряет процесс, особенно при большом количестве записей, благодаря параллельным обращениям к IndexedDB.
Для сложных условий фильтрации удобно строить универсальные функции:
async function searchByPredicate(predicate) {
const entries = await getAllEntriesParallel();
return entries.filter(({ key, value }) => predicate(key, value));
}
// Пример использования:
const results = await searchByPredicate((key, value) =>
value.age > 30 && value.name.startsWith('A')
);
predicate позволяет задавать любую логику поиска.Часто поиск по значениям применяется для динамических списков или таблиц. Ключевые моменты:
React или Vue, для повторного отображения без
повторного обращения к IndexedDB.let timeout;
inputElement.addEventListener('input', (e) => {
clearTimeout(timeout);
const query = e.target.value;
timeout = setTimeout(async () => {
const results = await searchByValue(query);
renderResults(results);
}, 300);
});
keys() и get() позволяют собрать весь
набор данных для поиска.filter() или пользовательский predicate
обеспечивают гибкую фильтрацию по значению.Promise.all ускоряют
получение больших объемов данных.