MongoDB 날짜 작업

MongoDBBeginner
지금 연습하기

소개

이 랩에서는 MongoDB 에서 날짜를 다루는 방법을 배우게 됩니다. 날짜 값을 가진 문서를 삽입하고, 특정 날짜 범위 내의 문서를 쿼리하고, 표시를 위해 날짜 필드를 형식화하고, 기존 날짜 필드를 업데이트하고, 날짜별로 컬렉션을 정렬하는 연습을 하게 됩니다. 이 랩은 시간 계열 데이터, 스케줄링 및 로깅 애플리케이션 관리에 필수적인 MongoDB 의 날짜 관련 기능에 대한 포괄적이고 실습적인 가이드를 제공합니다.

날짜 값으로 문서 삽입

첫 번째 단계에서는 MongoDB 서버에 연결하고 날짜 값을 포함하는 여러 문서를 삽입합니다. 이는 이후 단계에서 수행할 쿼리 및 작업의 기초가 됩니다.

먼저 터미널에서 mongosh 명령을 실행하여 MongoDB 셸을 엽니다. 이렇게 하면 실행 중인 MongoDB 인스턴스에 연결됩니다.

mongosh

셸에 들어가면 test>와 같은 프롬프트가 표시됩니다. 이제 datelab이라는 새 데이터베이스로 전환합니다. 데이터베이스가 존재하지 않으면 MongoDB 는 처음 데이터를 삽입할 때 자동으로 생성합니다.

use datelab

이제 events라는 새 컬렉션에 세 개의 문서를 삽입합니다. 각 문서는 이벤트를 나타내며 날짜를 포함합니다. MongoDB 는 날짜를 BSON Date 객체로 저장하며, 이는 new Date() 생성자를 사용하여 생성할 수 있습니다.

다음 문서를 하나씩 삽입합니다. 첫 번째는 ISO-8601 날짜 문자열을 사용하고, 두 번째는 현재 날짜 및 시간을 사용하며, 세 번째는 밀리초 단위의 Unix 타임스탬프를 사용합니다.

db.events.insertOne({
    event_name: "Conference",
    date: new Date("2024-06-15T10:30:00Z")
})
db.events.insertOne({
    event_name: "System Maintenance",
    timestamp: new Date()
})
db.events.insertOne({
    event_name: "Project Deadline",
    timestamp: new Date(1718476800000)
})

문서를 삽입한 후에는 컬렉션의 모든 문서를 검색하는 find() 메서드를 사용하여 올바르게 추가되었는지 확인할 수 있습니다.

db.events.find()

출력은 다음과 유사해야 합니다. 물론 _id 값과 "System Maintenance"의 timestamp는 사용자마다 다를 수 있습니다.

[
  {
    _id: ObjectId("65d38f8a1c2d3e4f5a6b7c8d"),
    event_name: 'Conference',
    date: ISODate('2024-06-15T10:30:00.000Z')
  },
  {
    _id: ObjectId("65d38f9c1c2d3e4f5a6b7c8e"),
    event_name: 'System Maintenance',
    timestamp: ISODate('2024-02-19T14:55:24.123Z')
  },
  {
    _id: ObjectId("65d38fb11c2d3e4f5a6b7c8f"),
    event_name: 'Project Deadline',
    timestamp: ISODate('2024-06-15T18:00:00.000Z')
  }
]

이제 날짜 값을 가진 문서를 성공적으로 삽입했습니다. 다음 단계에서는 이러한 문서를 날짜를 기준으로 쿼리하는 방법을 배우게 됩니다.

날짜 범위로 문서 쿼리

이제 컬렉션에 데이터가 있으므로 특정 날짜 범위 내의 문서를 찾기 위한 쿼리를 수행할 수 있습니다. 이는 예약된 이벤트, 로그 또는 시간 관련 데이터를 처리하는 애플리케이션에서 일반적인 요구 사항입니다.

먼저 쿼리를 더 흥미롭게 만들기 위해 컬렉션에 이벤트를 더 추가해 보겠습니다. insertMany() 메서드를 사용하여 세 개의 문서를 한 번에 추가합니다.

db.events.insertMany([
    {
        event_name: "Summer Conference",
        date: new Date("2024-07-15T09:00:00Z")
    },
    {
        event_name: "Winter Workshop",
        date: new Date("2024-01-20T14:30:00Z")
    },
    {
        event_name: "Spring Meetup",
        date: new Date("2024-04-10T11:15:00Z")
    }
])

이제 총 여섯 개의 이벤트가 있습니다. 2024 년 6 월 1 일 이후에 발생한 모든 이벤트를 찾아보겠습니다. 이를 위해 "보다 큼" 연산자인 $gt를 사용합니다.

db.events.find({
    date: { $gt: new Date("2024-06-01") }
})

다음으로 2024 년 상반기, 특히 1 월 1 일부터 6 월 1 일까지 발생한 모든 이벤트를 찾아보겠습니다. 이를 위해 "크거나 같음" ($gte) 및 "보다 작음" ($lt) 연산자를 결합할 수 있습니다.

db.events.find({
    date: {
        $gte: new Date("2024-01-01"),
        $lt: new Date("2024-06-01")
    }
})

이 쿼리는 "Winter Workshop" 및 "Spring Meetup" 이벤트를 반환합니다. 출력은 다음과 같아야 합니다.

[
  {
    _id: ObjectId("65d392a11c2d3e4f5a6b7c91"),
    event_name: 'Winter Workshop',
    date: ISODate('2024-01-20T14:30:00.000Z')
  },
  {
    _id: ObjectId("65d392a11c2d3e4f5a6b7c92"),
    event_name: 'Spring Meetup',
    date: ISODate('2024-04-10T11:15:00.000Z')
  }
]

이 예제들은 비교 연산자 ($gt, $gte, $lt, $lte) 를 사용하여 날짜 필드를 기준으로 문서를 효과적으로 필터링하는 방법을 보여줍니다.

Aggregation 을 사용한 날짜 출력 형식 지정

종종 날짜를 특정하고 사람이 읽을 수 있는 형식으로 표시해야 합니다. MongoDB 의 집계 프레임워크는 이를 위한 강력한 도구를 제공합니다. 이 단계에서는 $dateToString 연산자를 사용하여 날짜 필드를 형식화합니다.

집계 프레임워크는 단계를 거쳐 문서를 처리합니다. $project 단계를 사용하여 문서를 재구성하고 새롭고 형식화된 날짜 필드를 생성합니다.

events 컬렉션의 date 필드를 YYYY-MM-DD 형식으로 형식화해 보겠습니다. 이 쿼리는 date 필드가 있는 문서만 처리합니다.

db.events.aggregate([
    {
        $project: {
            event_name: 1,
            formatted_date: {
                $dateToString: {
                    format: "%Y-%m-%d",
                    date: "$date"
                }
            }
        }
    }
])

이 명령을 자세히 살펴보겠습니다.

  • db.events.aggregate([...]): events 컬렉션에서 집계 파이프라인을 시작합니다.
  • $project: 문서를 재구성하는 단계입니다. event_name을 포함하고 formatted_date라는 새 필드를 생성합니다.
  • $dateToString: 날짜 객체를 문자열로 변환하는 연산자입니다.
  • format: "%Y-%m-%d": 출력 형식을 지정합니다. %Y는 연도, %m은 월, %d는 일입니다.
  • date: "$date": 원본 문서의 입력 날짜 필드를 지정합니다. $ 접두사는 필드 경로를 나타냅니다.

출력에는 원본 이벤트 이름과 새로 형식화된 날짜 문자열이 표시됩니다. date 필드가 없는 문서 ("System Maintenance"와 같은) 는 결과에서 제외됩니다.

[
  { _id: ObjectId("..."), event_name: 'Conference', formatted_date: '2024-06-15' },
  { _id: ObjectId("..."), event_name: 'Summer Conference', formatted_date: '2024-07-15' },
  { _id: ObjectId("..."), event_name: 'Winter Workshop', formatted_date: '2024-01-20' },
  { _id: ObjectId("..."), event_name: 'Spring Meetup', formatted_date: '2024-04-10' }
]

$year$month와 같은 연산자를 사용하여 연도 또는 월과 같이 날짜의 개별 구성 요소를 추출할 수도 있습니다.

db.events.aggregate([
    {
        $project: {
            event_name: 1,
            year: { $year: "$date" },
            month: { $month: "$date" },
            day: { $dayOfMonth: "$date" }
        }
    }
])

이를 통해 날짜 정보를 처리하고 표시하는 방법에 대한 세밀한 제어를 얻을 수 있습니다.

날짜 필드 업데이트

데이터는 항상 고정되어 있지 않습니다. 이벤트 재예약 또는 수정 타임스탬프 추가와 같이 날짜 필드를 업데이트해야 할 수 있습니다. 이 단계에서는 다양한 업데이트 연산자를 사용하여 날짜 필드를 업데이트하는 방법을 배웁니다.

먼저 "Conference" 이벤트의 날짜를 새 날짜로 재예약해 보겠습니다. updateOne() 메서드를 사용하여 단일 문서를 대상으로 하고 $set 연산자를 사용하여 date 필드를 변경합니다.

db.events.updateOne(
    { event_name: "Conference" },
    {
        $set: {
            date: new Date("2024-09-01T10:00:00Z"),
            status: "Rescheduled"
        }
    }
)

이제 대량 업데이트를 수행해 보겠습니다. 2024 년 5 월 1 일 이전에 발생한 모든 이벤트를 "Archived"로 표시합니다. 또한 이 업데이트가 발생한 시점을 기록하기 위해 last_modified라는 새 필드를 추가합니다. updateMany() 메서드는 일치하는 모든 문서를 수정하며, $currentDate 연산자는 필드를 현재 서버 시간으로 설정하는 데 완벽합니다.

db.events.updateMany(
    { date: { $lt: new Date("2024-05-01") } },
    {
        $set: { status: "Archived" },
        $currentDate: { last_modified: true }
    }
)

모든 문서를 검색하여 변경 사항을 확인해 보겠습니다. .pretty() 메서드는 더 이상 사용되지 않으므로 find()만 사용합니다.

db.events.find()

"Conference"의 날짜와 상태가 변경되었음을 알 수 있습니다. "Winter Workshop" 및 "Spring Meetup"은 이제 "Archived"로 표시되고 last_modified 타임스탬프가 있습니다.

보관된 이벤트에 대한 예시 출력:

{
 "_id" : ObjectId("..."),
 "event_name" : "Winter Workshop",
 "date" : ISODate("2024-01-20T14:30:00Z"),
 "status" : "Archived",
 "last_modified" : ISODate("2024-02-19T15:10:00Z")
}

이러한 작업은 문서의 날짜 관련 정보를 정확하게 수정하는 방법을 보여줍니다.

날짜별 문서 정렬

배울 마지막 기본 작업은 정렬입니다. 이벤트를 시간순으로 표시하는 것은 일반적인 요구 사항입니다. MongoDB 를 사용하면 날짜를 포함한 모든 필드로 쿼리 결과를 쉽게 정렬할 수 있습니다.

문서를 정렬하려면 find() 쿼리에 .sort() 메서드를 추가합니다. sort() 메서드는 정렬할 필드와 정렬 순서를 지정하는 문서를 받습니다. 값 1은 오름차순 (가장 빠른 날짜부터 최신 날짜까지) 을 나타내고, -1은 내림차순 (최신 날짜부터 가장 빠른 날짜까지) 을 나타냅니다.

모든 이벤트를 date 필드를 기준으로 오름차순으로 정렬하여 검색해 보겠습니다.

db.events.find().sort({ date: 1 })

이렇게 하면 "Winter Workshop"(가장 빠른 날짜) 부터 "Summer Conference"(최신 날짜) 까지 이벤트가 나열됩니다. date 필드가 없는 문서는 쿼리에 포함된 경우 먼저 정렬됩니다.

이제 이벤트를 내림차순으로 정렬하여 최신 이벤트를 먼저 보겠습니다.

db.events.find().sort({ date: -1 })

정렬을 필터링과 결합할 수도 있습니다. 예를 들어, 보관되지 않은 모든 이벤트를 찾아 날짜별로 정렬해 보겠습니다.

db.events.find({ status: { $ne: "Archived" } }).sort({ date: 1 })

출력에는 보관되지 않은 이벤트가 시간순으로 표시됩니다.

[
  {
    _id: ObjectId("..."),
    event_name: 'System Maintenance',
    timestamp: ISODate("...")
  },
  {
    _id: ObjectId("..."),
    event_name: 'Project Deadline',
    timestamp: ISODate('2024-06-15T18:00:00.000Z')
  },
  {
    _id: ObjectId("..."),
    event_name: 'Summer Conference',
    date: ISODate('2024-07-15T09:00:00.000Z')
  },
  {
    _id: ObjectId("..."),
    event_name: 'Conference',
    date: ISODate('2024-09-01T10:00:00.000Z'),
    status: 'Rescheduled'
  }
]

정렬은 시간순으로 정렬된 데이터를 의미 있게 표시하는 데 중요한 도구입니다. 완료되면 exit를 입력하거나 Ctrl+D를 눌러 MongoDB 셸을 종료할 수 있습니다.

요약

이 랩에서는 MongoDB 에서 날짜를 다루는 기본적인 기술을 배웠습니다. 다양한 형식의 날짜 값을 사용하여 문서를 삽입하는 것부터 시작했습니다. 그런 다음 비교 연산자를 사용하여 날짜 범위를 기반으로 문서를 쿼리하는 연습을 했습니다. 그 후, 가독성을 높이기 위해 날짜 필드를 형식화하는 집계 프레임워크를 탐색했습니다. 또한 날짜 필드를 업데이트하고 수정 타임스탬프를 추가하는 방법을 배웠습니다. 마지막으로, 데이터를 시간순으로 표시하기 위해 컬렉션을 날짜별로 정렬하는 방법을 익혔습니다. 이러한 기술은 MongoDB 에서 시간 기반 데이터로 작업하는 모든 개발자에게 필수적입니다.