문서 메뉴

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

날짜 빼기(집계)

이 페이지의 내용

  • 정의
  • 행동
  • 예제
$dateSubtract

버전 5.0에 추가.

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

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

{
$dateSubtract: {
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으로 해석되는 표현식입니다. amount는 해당 값이 정밀도 손실 없이 long으로 변환될 수 있는 경우 정수/소수 또는 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 시간으로 작동합니다. dateSubtract 표현식은 항상 UTC로 startDate를 취하고 결과를 UTC로 반환합니다. timezone이 지정된 경우 지정된 timezone을 사용하여 계산이 수행됩니다. 표준 시간대는 계산에 일광 절약 시간제(DST)가 포함될 때 특히 중요합니다.

unitmonth 이상인 경우 해당 월의 마지막 날을 고려하도록 연산이 조정됩니다. 예를 들어 3월 마지막 날에 month 하나를 빼면 '당월 마지막 날짜' 조정이 나타납니다.

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

2월이 3월보다 날짜 수가 적기 때문에 반환된 날짜 ISODate("2021-02-28T12:10:05Z")은(는) 31일이 아니라 28일이라는 점에 유의하세요.

<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.connectionTime.insertMany(
[
{
custId: 457,
login: ISODate("2020-12-25T19:04:00"),
logout: ISODate("2020-12-28T09:04:00")
},
{
custId: 457,
login: ISODate("2021-01-27T05:12:00"),
logout: ISODate("2021-01-28T13:05:00")
},
{
custId: 458,
login: ISODate("2021-01-22T06:27:00"),
logout: ISODate("2021-01-31T11:00:00")
},
{
custId: 459,
login: ISODate("2021-02-14T20:14:00"),
logout: ISODate("2021-02-17T16:05:00")
},
{
custId: 460,
login: ISODate("2021-02-26T02:44:00"),
logout: ISODate("2021-02-18T14:13:00")
}
]
)

서비스 문제로 인해 2021년 1월 로그아웃 시간에서 각각 3시간을 빼야 합니다. aggregation pipeline에서 $dateSubtract을(를) 사용하여 logoutTime을(를) 줄일 수 있습니다.

db.connectionTime.aggregate(
[
{
$match:
{
$expr:
{
$eq:
[
{ $year: "$logout" },
2021
]
},
$expr:
{
$eq:
[
{ $month: "$logout" },
1
]
}
}
},
{
$project:
{
logoutTime:
{
$dateSubtract:
{
startDate: "$logout",
unit: "hour",
amount: 3
}
}
}
},
{
$merge: "connectionTime"
}
]
)

$match 단계에서는 두 가지 유사한 비교가 이루어집니다. 먼저 $year$month 연산자가 logoutTime 날짜 객체에서 각각 연도와 월을 추출합니다. 그런 다음 월과 연도가 선택 대상과 일치하는지 확인합니다. '1월'은 '1'로 인코딩되므로 연도와 월이 '2021' 및 '1'로 동일할($eq) 경우, $expr은 참이 됩니다.

$project 단계는 $dateSubtract를 사용해 선택한 각 문서의 logoutTime에서 3시간을 뺍니다.

마지막으로 $merge 단계에서는 collection을 업데이트하여 수정된 문서에 대해 새로운 logoutTime을 작성합니다.

참고

$out과 달리 $merge 컬렉션 단계에서는 일치하는 문서만 업데이트하고 나머지 컬렉션은 보존합니다. 자세한 내용은 $merge와 $out 비교를 참조하세요.

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

{
"_id" : ObjectId("603dd94b044b995ad331c0b5"),
"custId" : 457,
"login" : ISODate("2020-12-25T19:04:00Z"),
"logout" : ISODate("2020-12-28T09:04:00Z")
}
{
"_id" : ObjectId("603dd94b044b995ad331c0b6"),
"custId" : 457,
"login" : ISODate("2021-01-27T05:12:00Z"),
"logout" : ISODate("2021-01-28T13:05:00Z"),
"logoutTime" : ISODate("2021-01-28T10:05:00Z")
}
{
"_id" : ObjectId("603dd94b044b995ad331c0b7"),
"custId" : 458,
"login" : ISODate("2021-01-22T06:27:00Z"),
"logout" : ISODate("2021-01-31T11:00:00Z"),
"logoutTime" : ISODate("2021-01-31T08:00:00Z")
}
{
"_id" : ObjectId("603dd94b044b995ad331c0b8"),
"custId" : 459,
"login" : ISODate("2021-02-14T20:14:00Z"),
"logout" : ISODate("2021-02-17T16:05:00Z")
}
{
"_id" : ObjectId("603dd94b044b995ad331c0b9"),
"custId" : 460,
"login" : ISODate("2021-02-26T02:44:00Z"),
"logout" : ISODate("2021-02-18T14:13:00Z")
}

지난주에 서비스를 사용한 클라이언트에게 설문조사를 보내려고 합니다. $dateSubtract 표현식을 사용하면 쿼리가 실행되는 시간을 기준으로 범위 필터를 생성할 수 있습니다.

db.connectionTime.aggregate(
[
{
$match:
{
$expr:
{
$gt:
[
"$logoutTime",
{
$dateSubtract:
{
startDate: "$$NOW",
unit: "week",
amount: 1
}
}
]
}
}
},
{
$project:
{
_id: 0,
custId: 1,
loggedOut:
{
$dateToString:
{
format: "%Y-%m-%d",
date: "$logoutTime"
}
}
}
}
]
)

기본 제공 애그리게이션 변수 $$NOW는 현재 날짜/시간을 ISODate 형식으로 반환합니다. $match단계에서는 $$NOW의 값을 사용하여 오늘 날짜를 가져옵니다. 그런 다음 비교 표현식($expr)은 ($gt 및) $dateSubtract보다 큰 값을 사용하여 컬렉션을 필터링해 지난 주에 logoutTime이 있었던 문서와 일치시킵니다.

$project 단계에서는 $dateToString 표현식을 사용하여 날짜를 더 읽기 쉬운 형식으로 변환합니다. 변환이 없으면 MongoDB는 날짜를 ISODate 형식으로 반환합니다. 출력에는 지난 주에 고객 두 명이 로그아웃한 것으로 표시됩니다.

{ "custId" : 459, "loggedOut" : "2021-02-17" }
{ "custId" : 460, "loggedOut" : "2021-02-18" }

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

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

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

db.billing.insertMany(
[
{
location: "America/New_York",
login: ISODate("2021-03-14T10:00:00-0500"),
logout: ISODate("2021-03-14T18:00:00-0500")
},
{
location: "America/Mexico_City",
login: ISODate("2021-03-14T10:00:00-00:00"),
logout: ISODate("2021-03-15T08: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:
{
$dateSubtract:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
}
}
},
hours:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateSubtract:
{
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:
{
$dateSubtract:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
},
timezone: "$location"
}
},
hoursTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateSubtract:
{
startDate: "$login",
unit: "hour",
amount: 24,
timezone: "$location"
}
},
timezone: "$location"
}
},
}
}
]
).pretty()

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

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

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

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

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

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

다음도 참조하세요.

← $dateFromString (애그리게이션)

이 페이지의 내용