mongodb ObjectId 필드에서 타임스탬프를 추출하는 방법

$toDate: "$_id"

기존 데이터베이스에 createdTime, updatedTime을 추가하면서 알게 된 사실. 아래 방식으로 하면 _id: ObjectId 필드에서 타임스탬프를 꺼내어 정확한 createdTime을 만들어낼 수 있게 된다.

db.settlementPayment.updateMany(
  { createdTime: { $exists: false } },
  [
    {
      $set: {
        createdTime: { $toDate: "$_id" }, // Extract timestamp from `_id`
        updatedTime: new Date()
      }
    }
  ]
);

어떻게 이게 가능하지?

MongoDB에서 _id 필드는 기본적으로 ObjectId 타입이며, 이는 12바이트 크기의 BSON 데이터 타입이다. ObjectId는 다음과 같은 구조를 가진다:

바이트 설명
0-3 Unix Timestamp (초 단위)
4-8 머신 식별자
9-11 프로세스 ID + 카운터

따라서 _id의 앞 4바이트는 문서가 생성된 시간 정보를 포함하고 있다. MongoDB의 $toDate 연산자는 ObjectId에서 이 타임스탬프를 추출하여 ISODate 형식으로 변환한다.

즉, $toDate: "$_id"를 사용하면 _id 내부에 저장된 생성 시각을 정확하게 createdTime 필드로 설정할 수 있다. 이는 데이터가 생성될 당시 자동으로 부여된 _id를 활용하는 방식이므로, 별도의 타임스탬프 저장 없이도 문서 생성 시간을 정확하게 복원할 수 있다.

ObjectId의 타임스탬프를 수동으로 변환하는 방법

MongoDB에서 _id 필드에서 직접 타임스탬프를 추출하여 사람이 읽을 수 있는 날짜 형식으로 변환할 수도 있다. 이를 위해 여러 방법을 사용할 수 있다.

1. HEX -> DEC -> Unix Timestamp 변환

ObjectId의 앞 4바이트(8자리 HEX 값)를 직접 변환하여 Unix Timestamp를 얻을 수 있다.

const objectId = "65a2b3c4d5e6f7a8b9c0d1e2";
const hexTimestamp = objectId.substring(0, 8); // 앞 8글자 추출
const unixTimestamp = parseInt(hexTimestamp, 16); // HEX -> DEC 변환
const date = new Date(unixTimestamp * 1000); // Unix Timestamp -> 날짜 변환

console.log(date); // 출력: ISODate("2023-12-15T12:34:56.000Z")

2. JavaScript에서 변환하기

MongoDB의 ObjectId를 직접 분석하여 변환하는 방법:

const ObjectId = require('mongodb').ObjectId;
const id = new ObjectId("65a2b3c4d5e6f7a8b9c0d1e2");
const timestamp = id.getTimestamp();
console.log(timestamp); // 출력: ISODate("2023-12-15T12:34:56.000Z")

3. MongoDB에서 직접 변환하기

MongoDB 셸에서 ObjectId를 변환하는 방법:

ObjectId("65a2b3c4d5e6f7a8b9c0d1e2").getTimestamp()

이 코드를 실행하면 _id에서 추출된 생성 시간이 ISODate 형식으로 반환된다.

4. Python에서 변환하기

Python의 bson 라이브러리를 사용하면 ObjectId에서 타임스탬프를 쉽게 추출할 수 있다.

from bson import ObjectId

obj_id = ObjectId("65a2b3c4d5e6f7a8b9c0d1e2")
timestamp = obj_id.generation_time
print(timestamp)  # 출력: 2023-12-15 12:34:56+00:00

이러한 방식으로 ObjectId에서 생성된 시간을 쉽게 확인할 수 있으며, 직접 HEX 값을 변환하여 수동으로 Unix Timestamp로 변환하는 과정도 가능하다. 이를 활용하면 _id를 기반으로 데이터 생성 시간을 정확하게 복원할 수 있다.