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

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 работает в распределенных системах