sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB $dateFromString

En MongoDB, el $dateFromString El operador de canalización de agregación convierte una cadena de fecha/hora en un objeto de fecha.

Ejemplo

Supongamos que tenemos una colección llamada foo con los siguientes documentos:

{ "_id" : 1, "bar" : "2020-12-31T23:30:25.123" }
{ "_id" : 2, "bar" : "2020-12-31" }
{ "_id" : 3, "bar" : "2020-12-31T23:30" }

Todos los documentos contienen una cadena de fecha/hora.

Podemos ejecutar el siguiente código para devolver un objeto de fecha desde la bar campos en esos documentos.

db.foo.aggregate([ 
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar'
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") }
{ "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") }
{ "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") }

Todas las cadenas de fecha/hora se han convertido en un objeto de fecha.

También cambié el nombre del campo de bar a date .

Especifique un formato

Puede proporcionar un format opcional argumento para especificar el formato de la cadena de fecha/hora que se proporciona. La especificación de formato puede ser cualquier cadena literal, que contenga 0 o más especificadores de formato.

El format El parámetro está disponible desde MongoDB versión 4.0.

El formato predeterminado es %Y-%m-%dT%H:%M:%S.%LZ , que es lo que usa el ejemplo anterior.

Supongamos que insertamos el siguiente documento en nuestra colección:

{ "_id" : 4, "bar" : "07/08/2020" }

En este caso, la fecha podría ser el día 7 del mes 8 o el día 8 del mes 7, según la configuración regional que se utilice.

Podemos usar una especificación de formato para especificar exactamente cuál debería ser.

Ejemplo:

db.foo.aggregate([ 
  { $match: { _id: 4 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              format: "%m/%d/%Y"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") }

En este caso, especificamos que es el día 8 del mes 7.

Aquí está de nuevo, pero esta vez intercambiamos el día y el mes.

db.foo.aggregate([ 
  { $match: { _id: 4 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              format: "%d/%m/%Y"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 4, "date" : ISODate("2020-08-07T00:00:00Z") }

Esta vez se interpreta como el día 7 del mes 8.

Ver MongoDB $dateFromString Especificadores de formato para obtener una lista de especificadores de formato válidos.

Formato de fecha de semana ISO

Hay algunos especificadores de formato que le permiten especificar fechas utilizando el formato ISO 8601.

En particular, puede utilizar:

Especificador de formato Salida
%G Año en formato ISO 8601
%u Número del día de la semana en formato ISO 8601 (1 lunes, 7 domingo)
%V Semana del año en formato ISO 8601

Supongamos que tenemos un documento que se ve así:

{ "_id" : 5, "bar" : "7-8-2020" }

Podríamos interpretar esa fecha como el día 7 de la semana ISO, seguida de la semana ISO 8 del año, seguida del año.

Así:

db.foo.aggregate([ 
  { $match: { _id: 5 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              format: "%u-%V-%G"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 5, "date" : ISODate("2020-02-23T00:00:00Z") }

Especifique una zona horaria

Puede especificar una zona horaria para usar con $dateFromString operador.

La zona horaria se puede especificar utilizando el identificador de zona horaria de Olson (por ejemplo, "Europe/London" , "GMT" ) o el desplazamiento UTC (por ejemplo, "+02:30" , "-1030" ).

Identificador de zona horaria de Olson

Aquí hay un ejemplo que genera la cadena de fecha en tres zonas horarias diferentes, cada una con los ID de zona horaria de Olson:

db.foo.aggregate([ 
  { $match: { _id: 1 } },
  {
    $project: {
        utc: {
          $dateFromString: {
              dateString: '$bar',
              timezone: "UTC"
          }
        },
        honolulu: {
          $dateFromString: {
              dateString: '$bar',
              timezone: "Pacific/Honolulu"
          }
        },
        auckland: {
          $dateFromString: {
              dateString: '$bar',
              timezone: "Pacific/Auckland"
          }
        }
    }
  } 
]).pretty()

Resultado:

{
	"_id" : 1,
	"utc" : ISODate("2020-12-31T23:30:25.123Z"),
	"honolulu" : ISODate("2021-01-01T09:30:25.123Z"),
	"auckland" : ISODate("2020-12-31T10:30:25.123Z")
}

Desplazamiento UTC

Aquí hay un ejemplo que usa el desplazamiento UTC.

db.foo.aggregate([ 
  { $match: { _id: 1 } },
  {
    $project: {
        "date+00:00": {
          $dateFromString: {
              dateString: '$bar',
              timezone: "+00:00"
          }
        },
        "date-10:00": {
          $dateFromString: {
              dateString: '$bar',
              timezone: "-10:00"
          }
        },
        "date+12:00": {
          $dateFromString: {
              dateString: '$bar',
              timezone: "+12:00"
          }
        }
    }
  } 
]).pretty()

Resultado:

{
	"_id" : 1,
	"date+00:00" : ISODate("2020-12-31T23:30:25.123Z"),
	"date-10:00" : ISODate("2021-01-01T09:30:25.123Z"),
	"date+12:00" : ISODate("2020-12-31T11:30:25.123Z")
}

Si usa la timezone parámetro, la cadena de fecha no se puede agregar con una Z para indicar la hora zulú (zona horaria UTC). Por ejemplo, la cadena de fecha no puede ser 2020-12-31T23:30:25.123Z cuando se utiliza el parámetro de zona horaria.

Además, no incluya información de zona horaria en la cadena de fecha cuando utilice el parámetro de zona horaria.

El onNull Parámetro

El onNull El parámetro se puede usar para especificar qué devolver si la fecha es nula o no existe.

El valor proporcionado a onNull el parámetro puede ser cualquier expresión válida.

Supongamos que tenemos un documento como este:

{ "_id" : 6, "bar" : null }

Podríamos usar onNull de la siguiente manera:

db.foo.aggregate([ 
  { $match: { _id: 6 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              onNull: "No valid date was supplied"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 6, "date" : "No valid date was supplied" }

En este caso, la fecha era null y entonces el documento de salida incluye la cadena que proporcioné para onNull parámetro.

El onError Parámetro

Opcionalmente, puede usar el onError parámetro para proporcionar una expresión a la salida en caso de que ocurra un error.

Supongamos que nuestra colección contiene el siguiente documento:

{ "_id" : 7, "bar" : "21st Dec, 2030" }

Aunque hay una fecha en la bar campo, no es una cadena de fecha/hora válida y, por lo tanto, causará un error si usamos dateFromString para intentar convertirlo en un objeto de fecha.

Ejemplo de error:

db.foo.aggregate([ 
  { $match: { _id: 7 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar'
          }
        }
    }
  } 
])

Resultado:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "an incomplete date/time string has been found, with elements missing: \"21st Dec, 2030\"",
	"code" : 241,
	"codeName" : "ConversionFailure"
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:618:17
[email protected]/mongo/shell/assert.js:708:16
[email protected]/mongo/shell/db.js:266:5
[email protected]/mongo/shell/collection.js:1046:12
@(shell):1:1

Ese es un error que parece desagradable.

Podemos usar el onError parámetro para que se vea mejor:

db.foo.aggregate([ 
  { $match: { _id: 7 } },
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              onError: "An error occurred while parsing the date string"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 7, "date" : "An error occurred while parsing the date string" }

Ver como el onNull y onError Los parámetros nos permiten devolver los documentos reales, nos permiten devolver varios documentos, sin preocuparnos de que un documento incorrecto detenga toda la operación.

Ejemplo:

db.foo.aggregate([ 
  {
    $project: {
        date: {
          $dateFromString: {
              dateString: '$bar',
              onNull: "The date was either empty or null",
              onError: "An error occurred while parsing the date string"
          }
        }
    }
  } 
])

Resultado:

{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") }
{ "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") }
{ "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") }
{ "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") }
{ "_id" : 5, "date" : ISODate("2020-08-07T00:00:00Z") }
{ "_id" : 6, "date" : "The date was either empty or null" }
{ "_id" : 7, "date" : "An error occurred while parsing the date string" }