Как сделать уникальный номер документа в MongoDB

В MongoDB у каждого документа уже есть уникальный _id. Обычно это ObjectId, и для внутренней идентификации его достаточно. Но если вам нужен человекочитаемый номер заказа, заявки или счета, создайте отдельное поле, например number, поставьте на него уникальный индекс и генерируйте значение аккуратно

Пример документа:

{
  _id: ObjectId("665f1c1a7b8c2e0012a4d111"),
  number: 1001,
  status: "new",
  total: 2500
}

_id нужен базе, number удобен людям

Вариант 1. Использовать ObjectId

Если номер нужен только для поиска документа в приложении, ничего добавлять не нужно. Используйте _id:

db.orders.findOne({ _id: ObjectId("665f1c1a7b8c2e0012a4d111") })

Минус: такой номер длинный и неудобный для клиента

Вариант 2. Уникальный индекс на поле

Если номер задается приложением:

db.orders.createIndex({ number: 1 }, { unique: true })

Теперь MongoDB не позволит вставить два заказа с одинаковым number

Проверка:

db.orders.insertOne({ number: 1001, status: "new" })
db.orders.insertOne({ number: 1001, status: "new" })

Вторая вставка должна завершиться ошибкой повторяющегося значения

Вариант 3. Счетчик для последовательных номеров

Создайте коллекцию counters:

db.counters.insertOne({
  _id: "orderNumber",
  seq: 1000
})

Получение следующего номера:

const counter = db.counters.findOneAndUpdate(
  { _id: "orderNumber" },
  { $inc: { seq: 1 } },
  { returnDocument: "after" }
)

db.orders.insertOne({
  number: counter.seq,
  status: "new"
})

Смысл в том, что $inc увеличивает счетчик, а findOneAndUpdate возвращает новое значение

Что выбрать

Для внутренней логики используйте _id

Для публичного номера заказа используйте отдельное поле number

Для уникальности обязательно добавьте уникальный индекс

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

Частые ошибки

Делают номер через countDocuments

Если два запроса одновременно увидят одинаковое количество документов, они могут создать одинаковый номер. Так лучше не делать

Не добавляют уникальный индекс

Проверка в коде не заменяет ограничение в базе. Уникальный индекс — последняя защита от повторяющихся номеров

Используют номер как единственную защиту

Если пользователь открывает заказ по номеру, все равно проверяйте владельца заказа

Как сделать красивый номер

Часто в интерфейсе нужен не просто 1001, а номер вроде ORD-1001. В базе можно хранить число отдельно, а строку собирать в приложении:

{
  number: 1001,
  status: "new"
}

В интерфейсе:

ORD-1001

Так сортировка и поиск по числу остаются удобными. Если хранить весь номер строкой, не забывайте про одинаковую длину или отдельное числовое поле для сортировки

Проверка перед запуском

Перед включением последовательных номеров на рабочем проекте проверьте два параллельных создания документа. Если оба получают разные номера, счетчик работает правильно

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Как проверить результат на практике

Для MongoDB-материала полезно делать три проверки: сначала выполнить команду на маленьком наборе тестовых документов, затем посмотреть результат через find() или MongoDB Compass, а после этого повторить действие на копии реальной структуры данных. Если запрос меняет документы, сначала запускайте его с фильтром на один документ и только потом расширяйте условие

Еще одна хорошая привычка — записывать исходное состояние и ожидаемый результат. Например: было три документа, после обновления изменился только один; был массив из пяти элементов, после операции остался нужный элемент; индекс появился в getIndexes(). Такая проверка быстро показывает, что вы исправили именно задачу, а не просто получили команду без ошибки

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x