Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 범위 조건으로 ISODate 날짜 레코드 조회하는 방법

MongoDB에서 저장된 날짜 데이터 중 특정 시간대(예: 오전 6시~9시 사이)에 해당하는 레코드만 추출하고 싶은 경우가 있습니다. 이번 글에서는 ISODate 형식으로 저장된 날짜 필드를 대상으로, 집계 파이프라인의 $redact 연산자를 활용해 원하는 시간 범위의 문서만 조회하는 방법을 알아보겠습니다.

1. 샘플 컬렉션 생성

먼저 DueDate 필드에 ISODate 값을 담은 문서들을 삽입하여 테스트용 컬렉션을 만들어 보겠습니다.

> db.demo178.insertOne({"DueDate":new ISODate("2019-01-10T06:18:20.474Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e397bd89e4f06af551997f5")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-11-10T18:05:11.474Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e397bf39e4f06af551997f6")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-03-15T07:05:10.474Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e397c039e4f06af551997f7")
}
> db.demo178.insertOne({"DueDate":new ISODate("2020-06-11T16:05:10.474Z")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e397c0f9e4f06af551997f8")
}

2. 전체 문서 확인하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.

> db.demo178.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e397bd89e4f06af551997f5"), "DueDate" : ISODate("2019-01-10T06:18:20.474Z") }
{ "_id" : ObjectId("5e397bf39e4f06af551997f6"), "DueDate" : ISODate("2020-11-10T18:05:11.474Z") }
{ "_id" : ObjectId("5e397c039e4f06af551997f7"), "DueDate" : ISODate("2020-03-15T07:05:10.474Z") }
{ "_id" : ObjectId("5e397c0f9e4f06af551997f8"), "DueDate" : ISODate("2020-06-11T16:05:10.474Z") }

3. 시간 범위로 날짜 레코드 조회하기

이제 핵심인 조회 쿼리입니다. 아래 쿼리는 $redact 연산자와 $cond, $and, 그리고 날짜 연산자인 $hour를 조합하여, 시(hour) 값이 5보다 크고 9보다 작은 문서만 걸러냅니다.

> db.demo178.aggregate([
... {
...    "$redact": {
...       "$cond": {
...          "if": {
...             "$and": [
...                { "$gt": [ {"$hour": "$DueDate"}, 5] },
...                { "$lt": [ {"$hour": "$DueDate"}, 9] }
...             ]
...          },
...          "then": "$$KEEP",
...          "else": "$$PRUNE"
...       }
...    }
... }
...])

4. 실행 결과

조건에 맞는 문서만 반환되는 것을 확인할 수 있습니다.

{ "_id" : ObjectId("5e397bd89e4f06af551997f5"), "DueDate" : ISODate("2019-01-10T06:18:20.474Z") }
{ "_id" : ObjectId("5e397c039e4f06af551997f7"), "DueDate" : ISODate("2020-03-15T07:05:10.474Z") }

쿼리 동작 원리 정리

  • $hour: ISODate 값에서 시(hour) 부분만 숫자로 추출합니다. 예를 들어 06:18:20이면 6을 반환합니다.
  • $gt / $lt: 각각 초과, 미만 비교를 수행하여 시간이 5보다 크고 9보다 작은지 판단합니다.
  • $redact + $cond: 조건이 참이면 $$KEEP으로 해당 문서를 유지하고, 거짓이면 $$PRUNE으로 제거합니다.

결과적으로 오전 6시와 7시에 생성된 두 개의 문서만 남게 됩니다. 이처럼 $redact를 활용하면 별도의 $match 단계 없이도 날짜·시간 기반의 세밀한 필터링을 하나의 파이프라인 단계에서 처리할 수 있습니다. 만약 분(minute)이나 초(second) 단위까지 조건을 걸고 싶다면 $minute, $second 연산자를 동일한 방식으로 활용하면 됩니다.