В Dexie.js сортировка данных выполняется поверх индексированных
запросов IndexedDB и базируется на порядке значений в индексах. В
отличие от SQL-подобных систем, где сортировка может применяться к
произвольным полям через ORDER BY, в Dexie.js эффективная
сортировка достигается за счёт использования индексов или постобработки
результатов.
Ключевые инструменты сортировки:
sortBy() — извлекает данные, отсортированные по
указанному полюreverse() — инвертирует порядок уже отсортированного
набора данныхЭти методы применяются к объекту Collection, который
формируется после вызова where() или
toCollection().
sortBy(): базовая сортировка по индексуsortBy() используется для получения массива записей,
отсортированных по конкретному полю. Важно понимать, что этот метод
требует, чтобы поле было индексировано, иначе Dexie.js выполнит полное
сканирование таблицы.
Сигнатура:
table.sortBy(index)
Возвращаемое значение:
Promise<Array> — массив объектов, отсортированных
по значению указанного индексаsortBy()При вызове sortBy() Dexie.js:
Если индекс отсутствует:
sortBy()db.users.toArray()
db.users.orderBy('age').toArray()
db.users.orderBy('age').sortBy('age')
Более корректный и типичный вариант:
db.users.orderBy('age').toArray()
или:
db.users.toCollection().sortBy('age')
По умолчанию sortBy() всегда возвращает данные в порядке
возрастания:
const users = await db.users.toCollection().sortBy('age')
Результат:
sortBy()Несмотря на удобство, метод имеет ряд ограничений:
where())sortBy()При наличии индекса:
При отсутствии индекса:
Array.sort()reverse():
инверсия порядкаreverse() применяется к коллекции и изменяет направление
сортировки на обратное. Он не сортирует данные самостоятельно, а лишь
инвертирует уже заданный порядок.
Сигнатура:
collection.reverse()
Возвращает:
Collection, но с изменённым направлением
обходаreverse()Dexie.js управляет направлением обхода курсора IndexedDB:
forward — стандартное направление (ASC)reverse — обратное направление (DESC)Метод влияет только на итерацию, а не на данные.
reverse()const users = await db.users
.orderBy('age')
.reverse()
.toArray()
Результат:
reverse() с where()const result = await db.orders
.where('status')
.equals('completed')
.reverse()
.toArray()
Здесь:
statusreverse() от
sortBy()sortBy():
reverse():
Collection1. Получение самых новых записей
const latest = await db.logs
.orderBy('timestamp')
.reverse()
.limit(10)
.toArray()
2. Топ-N значений по убыванию
const topScores = await db.players
.orderBy('score')
.reverse()
.limit(5)
.toArray()
3. Сортировка без индекса (неэффективный вариант)
const users = await db.users.toCollection().sortBy('name')
Dexie.js применяет сортировку и направление в строгом порядке:
where() формирует выборкуorderBy() задаёт базовую сортировкуreverse() инвертирует порядокlimit() ограничивает результатtoArray() материализует коллекциюЛюбое изменение порядка шагов может привести к другому результату.
Индексы играют ключевую роль:
db.version(1).stores({
users: '++id, age, name'
})
При наличии индекса age:
db.users.orderBy('age').reverse()
Dexie использует индекс напрямую, избегая дополнительной сортировки.
sortBy() на неиндексированном поле без
понимания стоимости операцииreverse() изменяет данные (он меняет
только порядок обхода)sortBy() и reverse()
как взаимозаменяемые операцииПри индексе:
Без индекса:
Array.prototype.sort()const recent = await db.events
.orderBy('date')
.reverse()
.limit(20)
.toArray()
Такой подход часто используется для:
Если несколько записей имеют одинаковое значение индекса:
Для стабильной сортировки используется составной индекс:
db.version(1).stores({
users: '++id, age, name'
})
и дополнительная логика в приложении.