Перейти к основному содержимому

ObjectId

Поле типа ObjectId используется для хранения уникальных идентификаторов в формате MongoDB ObjectId.

Основные характеристики​

  • Тип данных: 12-байтовый идентификатор
  • Формат: 24-символьная шестнадцатеричная строка
  • Уникальность: Гарантированно уникальный
  • Временная метка: Содержит время создания
  • Автогенерация: Автоматически генерируется при создании

Структура ObjectId​

ObjectId состоит из:

  • 4 байта: Unix timestamp (секунды с 1 января 1970)
  • 5 байт: Случайное значение
  • 3 байта: Инкрементный счетчик

Пример: 507f1f77bcf86cd799439011

Настройки поля​

При создании поля типа "ObjectId" доступны следующие настройки:

  • Название поля: Отображаемое имя поля
  • Системное имя: Уникальный идентификатор для API
  • Описание: Подсказка для пользователей
  • Автогенерация: Автоматически генерировать при создании
  • Уникальность: Всегда уникальный

Примеры использования​

Первичный ключ​

{
"name": "_id",
"type": "objectid",
"auto": true,
"readonly": true
}

Ссылка на другую запись​

{
"name": "created_by",
"type": "objectid"
}

Внешний идентификатор​

{
"name": "external_id",
"type": "objectid"
}

Работа через API​

Автоматическая генерация​

// ObjectId генерируется автоматически
const record = await emd.database.collection('users').create({
name: 'Иван Иванов'
});

console.log(record._id); // "507f1f77bcf86cd799439011"

Создание с явным ObjectId​

import { ObjectId } from 'mongodb';

const customId = new ObjectId();

const record = await emd.database.collection('users').create({
_id: customId,
name: 'Иван Иванов'
});

Поиск по ObjectId​

// По строке
const record = await emd.database.collection('users').get('507f1f77bcf86cd799439011');

// По объекту ObjectId
import { ObjectId } from 'mongodb';
const record = await emd.database.collection('users').get(new ObjectId('507f1f77bcf86cd799439011'));

Сравнение ObjectId​

const id1 = '507f1f77bcf86cd799439011';
const id2 = '507f1f77bcf86cd799439011';

// Сравнение строк
console.log(id1 === id2); // true

// Сравнение объектов
import { ObjectId } from 'mongodb';
const objId1 = new ObjectId(id1);
const objId2 = new ObjectId(id2);
console.log(objId1.equals(objId2)); // true

Извлечение временной метки​

Получение времени создания​

import { ObjectId } from 'mongodb';

const objectId = new ObjectId('507f1f77bcf86cd799439011');
const timestamp = objectId.getTimestamp();

console.log(timestamp); // Date объект
console.log(timestamp.toISOString()); // "2012-10-17T20:46:47.000Z"

Сортировка по времени создания​

// ObjectId содержит временную метку, поэтому сортировка по _id
// эквивалентна сортировке по времени создания
const records = await emd.database.collection('users')
.find()
.sort({ _id: -1 }); // От новых к старым

Валидация ObjectId​

Проверка корректности​

import { ObjectId } from 'mongodb';

function isValidObjectId(id) {
return ObjectId.isValid(id);
}

console.log(isValidObjectId('507f1f77bcf86cd799439011')); // true
console.log(isValidObjectId('invalid-id')); // false

Валидация при создании​

try {
await emd.database.collection('users').create({
external_id: 'invalid-objectid'
});
} catch (error) {
console.error(error.message); // "Invalid ObjectId"
}

Генерация ObjectId​

На клиенте​

import { ObjectId } from 'bson'; // или 'mongodb'

const newId = new ObjectId();
console.log(newId.toString()); // "507f1f77bcf86cd799439011"

На сервере​

// ObjectId генерируется автоматически при создании записи
const record = await emd.database.collection('users').create({
name: 'Иван'
});

console.log(record._id);

Преобразование форматов​

ObjectId в строку​

import { ObjectId } from 'mongodb';

const objectId = new ObjectId();
const stringId = objectId.toString();
// "507f1f77bcf86cd799439011"

Строка в ObjectId​

import { ObjectId } from 'mongodb';

const stringId = '507f1f77bcf86cd799439011';
const objectId = new ObjectId(stringId);

ObjectId в HEX​

const objectId = new ObjectId();
const hexString = objectId.toHexString();
// "507f1f77bcf86cd799439011"

Поиск и фильтрация​

Поиск по списку ObjectId​

const ids = [
'507f1f77bcf86cd799439011',
'507f1f77bcf86cd799439012',
'507f1f77bcf86cd799439013'
];

const records = await emd.database.collection('users').find({
_id: { $in: ids }
});

Поиск записей, созданных после определенной даты​

import { ObjectId } from 'mongodb';

// Создать ObjectId для определенной даты
const date = new Date('2025-01-01');
const objectId = ObjectId.createFromTime(date.getTime() / 1000);

// Найти все записи, созданные после этой даты
const records = await emd.database.collection('users').find({
_id: { $gt: objectId }
});

Поиск записей за период​

import { ObjectId } from 'mongodb';

const startDate = new Date('2025-01-01');
const endDate = new Date('2025-12-31');

const startId = ObjectId.createFromTime(startDate.getTime() / 1000);
const endId = ObjectId.createFromTime(endDate.getTime() / 1000);

const records = await emd.database.collection('users').find({
_id: {
$gte: startId,
$lte: endId
}
});

Использование в связях​

Ссылка на пользователя​

const user = await emd.database.collection('users').get(userId);

const task = await emd.database.collection('tasks').create({
title: 'Задача',
created_by: user._id // ObjectId пользователя
});

Получение связанных данных​

const task = await emd.database.collection('tasks').get(taskId);

// Получить пользователя по ObjectId
const user = await emd.database.collection('users').get(task.created_by);

Индексация​

ObjectId автоматически индексируется как первичный ключ:

// _id всегда имеет уникальный индекс
await emd.database.collection('users').createIndex({ _id: 1 });

Производительность​

Преимущества ObjectId​

  • Быстрая генерация (не требует обращения к БД)
  • Гарантированная уникальность
  • Встроенная временная метка
  • Компактный размер (12 байт)
  • Хорошо индексируется

Сравнение с другими типами ID​

  • ObjectId vs UUID: ObjectId меньше (12 vs 16 байт), содержит timestamp
  • ObjectId vs Auto-increment: ObjectId не требует синхронизации, работает в распределенных системах
  • ObjectId vs String: ObjectId более эффективен для индексации

Отображение в интерфейсе​

Короткая форма​

function shortId(objectId) {
return objectId.toString().substring(0, 8) + '...';
}

// "507f1f77..."

Копирование в буфер обмена​

function copyObjectId(objectId) {
navigator.clipboard.writeText(objectId.toString());
}

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

  • Используйте ObjectId для первичных ключей (_id)
  • Используйте ObjectId для ссылок между коллекциями
  • Не используйте ObjectId для пользовательских идентификаторов (используйте UUID или slug)
  • Всегда валидируйте ObjectId перед использованием
  • Используйте встроенную временную метку вместо отдельного поля created_at
  • Для отображения пользователям используйте короткую форму или дружественный ID

Безопасность​

Предсказуемость​

ObjectId содержит временную метку, что делает его частично предсказуемым. Для публичных ID используйте UUID.

Раскрытие информации​

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

Отличие от других типов​

  • ObjectId vs UUID: ObjectId меньше, содержит timestamp, специфичен для MongoDB
  • ObjectId vs String: ObjectId типизирован, валидируется, эффективнее
  • ObjectId vs Auto-increment: ObjectId работает в распределенных системах