Подсчёт записей

idb-keyval — это лёгкая библиотека для работы с IndexedDB в JavaScript, предоставляющая удобный асинхронный API для сохранения, получения и удаления данных. Одной из распространённых задач при работе с базой данных является подсчёт количества записей. В отличие от сложного API IndexedDB, idb-keyval упрощает этот процесс и позволяет оперировать коллекциями данных без ручного управления транзакциями.


Использование метода keys() для подсчёта записей

Простейший способ определить количество элементов в хранилище — получить все ключи и вычислить их длину массива:

import { keys } from 'idb-keyval';

async function countRecords() {
    const allKeys = await keys();
    return allKeys.length;
}

countRecords().then(count => {
    console.log(`Всего записей: ${count}`);
});

Ключевые моменты:

  • Функция keys() возвращает массив всех ключей, хранящихся в базе.
  • Для получения количества достаточно просто измерить длину массива allKeys.length.
  • Этот метод подходит для небольших и средних наборов данных, так как для больших объёмов получение всех ключей может быть ресурсоёмким.

Подсчёт записей с фильтрацией

В некоторых случаях требуется подсчитать записи по определённому критерию, например, только те элементы, ключ которых соответствует шаблону. Для этого комбинируют keys() и фильтрацию массивов:

import { keys, get } from 'idb-keyval';

async function countFilteredRecords(prefix) {
    const allKeys = await keys();
    const filteredKeys = allKeys.filter(key => key.startsWith(prefix));
    return filteredKeys.length;
}

countFilteredRecords('user_').then(count => {
    console.log(`Количество записей с префиксом "user_": ${count}`);
});

Особенности подхода:

  • Позволяет использовать любые правила фильтрации: по префиксу, по типу данных ключа или сложным условиям.
  • При необходимости можно одновременно получать и значения для дальнейшей обработки через get().

Подсчёт записей с использованием entries()

Для получения более точного контроля можно использовать метод entries(), который возвращает пары [ключ, значение]. Такой подход полезен, если требуется одновременно подсчитать и анализировать содержимое:

import { entries } from 'idb-keyval';

async function countRecordsByValueType(type) {
    const allEntries = await entries();
    const filtered = allEntries.filter(([key, value]) => typeof value === type);
    return filtered.length;
}

countRecordsByValueType('number').then(count => {
    console.log(`Записей с числовыми значениями: ${count}`);
});

Преимущества метода entries():

  • Позволяет фильтровать данные по содержимому, а не только по ключам.
  • Обеспечивает гибкость при сложных условиях подсчёта.
  • Удобно использовать для статистики и аналитики по данным.

Создание универсальной функции подсчёта

Для повторного использования можно создать обобщённую функцию, которая принимает параметры фильтрации и возвращает количество записей:

import { entries } from 'idb-keyval';

async function countRecords(filterFn = null) {
    const allEntries = await entries();
    if (!filterFn) return allEntries.length;
    return allEntries.filter(([key, value]) => filterFn(key, value)).length;
}

// Пример использования:
countRecords(([key, value]) => key.startsWith('session_') && typeof value === 'object')
    .then(count => console.log(`Количество сессий: ${count}`));

Особенности такой функции:

  • Может принимать любой фильтр, определяемый функцией filterFn.
  • Если фильтр не задан, возвращает общее количество всех записей.
  • Позволяет гибко управлять подсчётом без дублирования кода.

Производительность и ограничения

  • Для небольших и средних хранилищ подсчёт через keys() или entries() выполняется быстро.
  • Для больших объёмов данных стоит избегать одновременного получения всех значений, так как это может потреблять много памяти и времени.
  • В случаях с миллионами записей лучше рассматривать использование собственных транзакций IndexedDB или хранение счётчика отдельно, чтобы избегать перебора всех элементов.

Асинхронность и обработка ошибок

Все методы idb-keyval возвращают промисы, поэтому подсчёт записей должен учитывать асинхронность:

async function safeCountRecords() {
    try {
        const count = await keys().then(keys => keys.length);
        console.log(`Всего записей: ${count}`);
    } catch (error) {
        console.error('Ошибка при подсчёте записей:', error);
    }
}

safeCountRecords();

Рекомендации:

  • Обязательно использовать try/catch для обработки возможных ошибок при доступе к IndexedDB.
  • Асинхронная модель позволяет не блокировать основной поток выполнения при больших операциях.

Итоговая схема подсчёта

  1. Определить способ подсчёта: по ключам (keys()) или с анализом значений (entries()).
  2. При необходимости применить фильтры или условия.
  3. Использовать асинхронную обработку с async/await.
  4. Для больших данных рассмотреть альтернативные подходы, чтобы избежать перебора всех записей.

Такой подход обеспечивает гибкость, простоту и эффективность подсчёта записей в хранилище idb-keyval, позволяя строить статистику и управлять данными без сложного кода.