Docs Menu
Docs Home
/ /
Operadores de tuberías de agregación

$dateSubtract (operador de agregación)

$dateSubtract

Nuevo en la versión 5.0.

Disminuye a Objeto de fecha por un número específico de unidades de tiempo.

La expresión $dateSubtract tiene la siguiente sintaxis:

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

Devuelve una fecha.startDate puede ser cualquier expresión que se resuelva en tipo Fecha, Marca de tiempo u ObjectId. Independientemente del tipo de dato utilizado como entrada, el valor devuelto será un objeto Fecha.

Campo
Obligatorio/Opcional
Descripción

startDate

Requerido

La fecha de inicio, en UTC, de la operación de resta. El startDate puede ser cualquier expresión que se resuelva en una fecha, una marca de tiempo o un ID de objeto.

unit

Requerido

El unit se utiliza para medir el amount de tiempo restado startDate del. El unit es una expresión que se resuelve en una de las siguientes cadenas:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

amount

Requerido

El número de units restado startDate de.amount es una expresión que se resuelve en un entero o long.amount también puede resolverse en un decimal entero o double si ese valor se puede convertir a long sin pérdida de precisión.

timezone

Opcional

La zona horaria para realizar la operación. <tzExpression> debe ser una expresión válida que se resuelva en una cadena formateada como un identificador de zona horaria de Olsono una diferencia UTC. Si no timezone se proporciona, el resultado se muestra UTC en.

Formato
Ejemplos

Identificador de zona horaria de Olson

"America/New_York"
"Europe/London"
"GMT"

Desplazamiento UTC

+/-[hh]:[mm], e.g. "+04:45"
+/-[hh][mm], e.g. "-0530"
+/-[hh], e.g. "+03"

Para obtener más información sobre expresiones y tipos, consulte Expresiones y tipos BSON.

MongoDB sigue el uso prevalente de bases de datos y trabaja con el tiempo en UTC. La expresión dateSubtract siempre toma un startDate en UTC y devuelve un resultado en UTC. Si se especifica el timezone, el cálculo se realizará utilizando el timezone especificado. La zona horaria es especialmente importante cuando un cálculo implica el horario de verano (DST).

Si unit es month o mayor, la operación se ajusta para tener en cuenta el último día del mes. Restar un month al último día de marzo, por ejemplo, demuestra el ajuste del "último día del mes".

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

Tenga en cuenta que la fecha devuelta, ISODate("2021-02-28T12:10:05Z"), es la 28y no la 31ya que febrero tiene menos días que marzo.

Al utilizar un identificador de zona horaria de Olson en el campo <timezone>, MongoDB aplica el Desplazamiento del horario de verano, si corresponde para la zona horaria especificada.

Por ejemplo, considera una colección sales con el siguiente documento:

db.sales.insertOne(
{
"_id" : 1,
"item" : "abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate("2014-01-01T08:15:39.736Z")
}
)

La siguiente agregación ilustra cómo MongoDB gestiona la diferencia horaria del identificador de zona horaria Olson. El ejemplo utiliza los operadores $hour y para devolver las partes correspondientes del $minute date campo:

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" }
}
}
}])

La operación devuelve el siguiente resultado:

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

Considere una colección de tiempos de conexión del sistema como estos:

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")
}
]
)

Debido a un problema de servicio, debe restar 3 horas de cada cierre de sesión de enero 2021. Puede usar $dateSubtract en una secuencia de agregación para restar 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"
}
]
)

Se realizan dos comparaciones similares en la etapa$match. Primero, los operadores$yeary$monthextraen el año y el mes, respectivamente, del objeto de fecha logoutTime. A continuación, se comprueba si el mes y el año coinciden con los objetivos de selección. Dado que "enero" se codifica como "1", $expres verdadero cuando el año y el mes son iguales ($eq) a "2021" y "1".

La etapa $project utiliza $dateSubtract para restar 3 horas de las logoutTime de cada documento seleccionado.

Finalmente, la etapa actualiza la colección, escribiendo el $merge nuevo logoutTime para los documentos modificados.

Nota

A diferencia de,$out la $merge etapa solo actualiza los documentos coincidentes y conserva el resto de la colección. Para más detalles, consulte: $out comparado con $merge.

Los documentos resultantes se ven así:

{
"_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")
}

Quiere enviar una encuesta a los clientes que usaron su servicio la semana pasada. La expresión $dateSubtract puede crear un filtro de rango relativo a la hora de ejecución de la consulta.

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"
}
}
}
}
]
)

La variable de agregación integrada$$NOWdevuelve la fecha y hora actual en formato ISODate. La etapa$matchutiliza el valor de$$NOWpara obtener la fecha actual. A continuación, la expresión de comparación ($expr) filtra la colección utilizando valores mayores que ($gt) y $dateSubtract para encontrar los documentos con un valor de logoutTime en la última semana.

La etapa $project usa la expresión para convertir las fechas a un formato $dateToString más legible. Sin la conversión, MongoDB devolvería la fecha en formato ISODate. El resultado muestra que dos clientes cerraron sesión la semana pasada.

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

Todas las fechas se almacenan internamente en hora UTC. Cuando se especifica timezone, $dateSubtract utiliza la hora local para realizar los cálculos. Los resultados se muestran en UTC.

Tiene clientes en varias zonas horarias y desea ver qué efecto podría tener el horario de verano en sus períodos de facturación si factura antes del day o del hour.

Crea esta colección de tiempos de conexión:

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")
}
]
)

Primero reste 1 día, luego reste 24 horas de las login fechas en cada documento.

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()

La expresión reformatea la salida para facilitar su lectura. Los resultados se resumen a $dateToString continuación:

Campo
New York
Ciudad de México

Inicio

2021-03-14 15:00

2021-03-14 15:00

Inicio, información de TZ

2021-03-14 11:00

2021-03-14 04:00

1 día

2021-03-13 16:00

2021-03-13 15:00

1 Día, TZInfo

2021-03-13 11:00

2021-03-13 09:00

24 Horas

2021-03-13 15:00

2021-03-13 15:00

24 Horas, TZInfo

2021-03-13 10:00

2021-03-13 09:00

El gráfico destaca varios puntos:

  • Las fechas sin formato se muestran en UTC. El $login de Nueva York es UTC -5; sin embargo, las filas start, days y hours muestran la hora en UTC.

  • El 14de marzo marca el inicio del horario de verano en Nueva York, pero no en México. La hora calculada se ajusta cuando una ubicación cambia al horario de verano y pasa de un day a otro.

  • El horario de verano (DST) modifica la duración de day, no de hour. No hay horario de verano (DST) para hours. Solo hay un ajuste por horario de verano (DST) cuando la medición unit es de day o más y el cálculo cruza un cambio de horario en el timezone especificado.

Tip

Volver

$dateFromString

En esta página