날짜 추가(집계)
정의
$dateAdd
버전 5.0에 추가.
Date 객체 를 지정된 시간 단위만큼 증가시킵니다.
$dateAdd
표현식의 구문은 다음과 같습니다.{ $dateAdd: { startDate: <Expression>, unit: <Expression>, amount: <Expression>, timezone: <tzExpression> } } 날짜 를 반환합니다.
startDate
는 날짜, 타임스탬프 또는 ObjectId 유형으로 해석되는 모든 표현식일 수 있습니다. 어떤 데이터 유형이 입력으로 사용되든 반환되는 값은 Date 객체가 됩니다.필드필수/선택 사항설명startDate
필수 사항
unit
필수 사항
unit
은startDate
에 추가된 시간의amount
를 측정하는 데 사용됩니다.unit
은 다음 문자열 중 하나로 해석되는 표현식 입니다.year
quarter
week
month
day
hour
minute
second
millisecond
amount
필수 사항
startDate
에 추가된units
의 수.amount
는 정수 또는 long으로 리졸브되는 표현식입니다. 값이 정밀도 손실 없이 long으로 변환될 수 있는 경우amount
는 정수/소수 또는 double 표시할 수도 있습니다.timezone
옵션
작업을 수행할 표준 시간대입니다. 은 Olson 표준 시간대
<tzExpression>
식별자 형식의 string 로 해석되는 유효한 표현식 이어야 합니다. 또는 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)가 포함될 때 특히 중요합니다.
unit
이 month
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일입니다. 집계 파이프라인에서 $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
표현식은 가독성을 위해 출력 형식을 다시 지정합니다. 결과는 다음과 같이 요약됩니다.
필드 | New York | 멕시코 시티 |
---|---|---|
시작하기 | 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를 조정할 수 있습니다.