문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

날짜 추가(집계)

이 페이지의 내용

  • 정의
  • 행동
  • 예제
$dateAdd

버전 5.0에 추가.

지정된 시간 단위만큼 Date 객체를 증가시킵니다.

$dateAdd 표현식의 구문은 다음과 같습니다.

{
$dateAdd: {
startDate: <Expression>,
unit: <Expression>,
amount: <Expression>,
timezone: <tzExpression>
}
}

날짜 를 반환합니다. startDate 는 날짜, 타임스탬프 또는 ObjectId 유형으로 해석되는 모든 표현식일 수 있습니다. 어떤 데이터 유형이 입력으로 사용되든 반환되는 값은 Date 객체가 됩니다.

필드
필수/선택 사항
설명
startDate
필수 사항
추가 작업의 시작 날짜(UTC 기준)입니다. startDate날짜, 타임스탬프, 또는 객체 ID로 해석되는 모든 표현식이 될 수 있습니다.
unit
필수 사항

unitstartDate에 추가된 시간의 amount를 측정하는 데 사용됩니다. unit은 다음 문자열 중 하나로 해석되는 표현식 입니다.

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

amount
필수 사항
startDate에 추가된 units의 수. amount는 정수 또는 long으로 리졸브되는 표현식입니다. 값이 정밀도 손실 없이 long으로 변환될 수 있는 경우 amount는 정수/소수 또는 double 표시할 수도 있습니다.
timezone
옵션

작업을 수행할 표준 시간대입니다. 은<tzExpression> Olson 표준 시간대 식별자 형식의 문자열로 해석되는 유효한 표현식 이어야 합니다. 또는 UTC 오프셋 . 이 제공되지 timezone 않으면 결과가 UTC 에 표시됩니다.

형식
예제
Olson 표준 시간대 ID
"America/New_York"
"Europe/London"
"GMT"
UTC 오프셋
+/-[hh]:[mm], e.g. "+04:45"
+/-[hh][mm], e.g. "-0530"
+/-[hh], e.g. "+03"

표현식 및 유형에 대한 자세한 내용은 표현식BSON types를 참조하세요.

MongoDB는 일반적인 데이터베이스 사용법을 따르며 UTC 시간으로 작동합니다. dateAdd 표현식은 항상 UTC로 startDate를 취하고 결과를 UTC로 반환합니다. timezone이 지정된 경우 지정된 timezone을 사용하여 계산이 수행됩니다. 표준 시간대는 계산에 일광 절약 시간제(DST)가 포함될 때 특히 중요합니다.

unitmonth 1 이상인 경우 당월 마지막 날을 고려하여 작업이 조정됩니다. 예를 들어, 10월 마지막 날에 month 1을 추가하면 '당월 마지막 날짜' 조정이 나타납니다.

{
$dateAdd:
{
startDate: ISODate("2020-10-31T12:10:05Z"),
unit: "month",
amount: 1
}
}

11월이 10월보다 날짜 수가 적기 때문에 반환된 날짜 ISODate("2020-11-30T12:10:05Z") 는 31일이 아니라 30일임을 알 수 있습니다.

<timezone> 필드에서 Olson 표준 시간대 ID를 사용할 때 MongoDB는 지정된 시간대에 적용 가능한 경우 DST 오프셋을 적용합니다.

예를 들어 sales 다음 문서가 있는 컬렉션을 생각해 보겠습니다.

{
"_id" : 1,
"item" : "abc",
"price" : 20,
"quantity" : 5,
"date" : ISODate("2017-05-20T10:24:51.303Z")
}

다음 애그리게이션은 MongoDB가 Olson 시간대 식별자에 대한 DST 오프셋을 처리하는 방법을 보여 줍니다. 이 예제에서는 $hour$minute 연산자를 사용하여 date 필드의 해당 부분을 반환합니다.

db.sales.aggregate([
{
$project: {
"nycHour": {
$hour: { date: "$date", timezone: "-05:00" }
},
"nycMinute": {
$minute: { date: "$date", timezone: "-05:00" }
},
"gmtHour": {
$hour: { date: "$date", timezone: "GMT" }
},
"gmtMinute": {
$minute: { date: "$date", timezone: "GMT" } },
"nycOlsonHour": {
$hour: { date: "$date", timezone: "America/New_York" }
},
"nycOlsonMinute": {
$minute: { date: "$date", timezone: "America/New_York" }
}
}
}])

이 연산은 다음과 같은 결과를 반환합니다.

{
"_id": 1,
"nycHour" : 5,
"nycMinute" : 24,
"gmtHour" : 10,
"gmtMinute" : 24,
"nycOlsonHour" : 6,
"nycOlsonMinute" : 24
}

다음과 같은 문서가 포함된 고객 주문 컬렉션이 있다고 가정해 보겠습니다.

db.shipping.insertMany(
[
{ custId: 456, purchaseDate: ISODate("2020-12-31") },
{ custId: 457, purchaseDate: ISODate("2021-02-28") },
{ custId: 458, purchaseDate: ISODate("2021-02-26") }
]
)

일반적인 배송 시간은 3일입니다. Aggregation pipeline에서 $dateAdd를 사용하여 expectedDeliveryDate를 향후 3일로 설정할 수 있습니다.

db.shipping.aggregate(
[
{
$project:
{
expectedDeliveryDate:
{
$dateAdd:
{
startDate: "$purchaseDate",
unit: "day",
amount: 3
}
}
}
},
{
$merge: "shipping"
}
]
)

$project 단계에서 $dateAdd를 사용하여 purchaseDate에 3일을 추가한 후 $merge 단계에서는 원본 문서를 expectedDeliveryDate로 업데이트합니다.

결과 문서는 다음과 같이 표시됩니다.

{
"_id" : ObjectId("603dd4b2044b995ad331c0b2"),
"custId" : 456,
"purchaseDate" : ISODate("2020-12-31T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-01-03T00:00:00Z")
}
{
"_id" : ObjectId("603dd4b2044b995ad331c0b3"),
"custId" : 457,
"purchaseDate" : ISODate("2021-02-28T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-03-03T00:00:00Z")
}
{
"_id" : ObjectId("603dd4b2044b995ad331c0b4"),
"custId" : 458,
"purchaseDate" : ISODate("2021-02-26T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-03-01T00:00:00Z")
}

이 코드로 마지막 예제의 shipping 컬렉션을 업데이트하여 문서에 배송 날짜를 추가합니다.

db.shipping.updateOne(
{ custId: 456 },
{ $set: { deliveryDate: ISODate( "2021-01-10" ) } }
)
db.shipping.updateOne(
{ custId: 457 },
{ $set: { deliveryDate: ISODate( "2021-03-01" ) } }
)
db.shipping.updateOne(
{ custId: 458 },
{ $set: { deliveryDate: ISODate( "2021-03-02" ) } }
)

지연된 배송을 찾으려고 합니다. $match 단계에서 $dateAdd를 사용하여 시작점($purchaseDate)으로 정의된 날짜 범위와 $dateAdd로 지정된 기간의 문서와 일하는 필터를 생성합니다.

db.shipping.aggregate(
[
{
$match:
{
$expr:
{
$gt:
[ "$deliveryDate",
{
$dateAdd:
{
startDate: "$purchaseDate",
unit: "day",
amount: 5
}
}
]
}
}
},
{
$project:
{
_id: 0,
custId: 1,
purchased:
{
$dateToString:
{
format: "%Y-%m-%d",
date: "$purchaseDate"
}
},
delivery:
{
$dateToString:
{
format: "%Y-%m-%d",
date: "$deliveryDate"
}
}
}
}
]
)

$match 단계에서는 표현식($expr)에 $gt$dateAdd를 사용하여 실제 deliveryDate를 예상 날짜와 비교합니다. 배송 날짜가 purchaseDate 이후 5일이 지난 문서는 $project 단계로 넘어갑니다.

$project 단계에서는 $dateToString 표현식을 사용하여 날짜를 더 읽기 쉬운 형식으로 변환합니다. 변환이 없으면 MongoDB는 날짜를 ISODate 형식으로 반환합니다.

이 예제에서는 하나의 레코드만 반환됩니다.

{ "custId" : 456, "purchased" : "2020-12-31", "delivery" : "2021-01-10" }

모든 날짜는 내부적으로 UTC 시간으로 저장됩니다. timezone을 지정하면 $dateAdd는 현지 시간을 사용하여 계산을 수행합니다. 결과는 UTC로 표시됩니다.

고객이 여러 시간대에 있으며 day 또는 hour을(를) 기준으로 청구할 경우 서머타임이 청구 기간에 어떤 영향을 주는지 확인하려고 합니다.

다음과 같은 연결 시간 컬렉션을 생성합니다.

db.billing.insertMany(
[
{
location: "America/New_York",
login: ISODate("2021-03-13T10:00:00-0500"),
logout: ISODate("2021-03-14T18:00:00-0500")
},
{
location: "America/Mexico_City",
login: ISODate("2021-03-13T10:00:00-00:00"),
logout: ISODate("2021-03-14T08:00:00-0500")
}
]
)

먼저 1일을 추가하고 각 문서의 login 날짜에 24시간을 추가합니다.

db.billing.aggregate(
[
{
$project:
{
_id: 0,
location: 1,
start:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date: "$login"
}
},
days:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
}
}
},
hours:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "hour",
amount: 24,
timezone: "$location"
}
}
}
},
startTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date: "$login",
timezone: "$location"
}
},
daysTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
},
timezone: "$location"
}
},
hoursTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "hour",
amount: 24,
timezone: "$location"
}
},
timezone: "$location"
}
},
}
}
]
).pretty()

$dateToString 표현식은 가독성을 위해 출력 형식을 다시 지정합니다. 결과는 다음과 같이 요약됩니다.

필드
뉴욕
멕시코 시티
시작하기
2021-03-13 15:00
2021-03-13 10:00
시작, TZ 정보
2021-03-13 10:00
2021-03-13 04:00
1일
2021-03-14 14:00
2021-03-14 10:00
1일, TZ 정보
2021-03-14 10:00
2021-03-14 04:00
24시간
2021-03-14 15:00
2021-03-14 10:00
24시간, TZ 정보
2021-03-14 11:00
2021-03-14 04:00

이 차트는 다음과 같은 요점 몇 가지를 몇 가지 요점을 강조해 보여줍니다.

  • 형식이 지정되지 않은 날짜는 UTC로 반환됩니다. 뉴욕의 $login은 UTC -5이지만 start, days, hours 행은 시간을 UTC로 표시합니다.

  • 3월 14일에는 뉴욕에서 서머타임이 시작되지만, 멕시코에서는 그렇지 않습니다. 계산된 시간은 위치가 DST로 전환되고 한 day에서 다음으로 넘어갈 때 조정됩니다.

  • DST는 hour이 아닌 day의 길이를 수정합니다. hours 관련 DST 변경 사항이 없습니다. unit 측정값이 day 이상이고 계산이 지정된 timezone 시간 변화와 교차하는 경우에만 DST를 조정할 수 있습니다.

다음도 참조하세요.

← 공분산샘플(집계)

이 페이지의 내용