In MongoDB, il $dateFromString
l'operatore della pipeline di aggregazione converte una stringa di data/ora in un oggetto data.
Esempio
Supponiamo di avere una collezione chiamata foo
con i seguenti documenti:
{ "_id" : 1, "bar" : "2020-12-31T23:30:25.123" } { "_id" : 2, "bar" : "2020-12-31" } { "_id" : 3, "bar" : "2020-12-31T23:30" }
Tutti i documenti contengono una stringa di data/ora.
Possiamo eseguire il codice seguente per restituire un oggetto data dalla bar
campi in quei documenti.
db.foo.aggregate([
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Risultato:
{ "_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") }
Tutte le stringhe di data/ora sono state convertite in un oggetto data.
Ho anche cambiato il nome del campo da bar
a date
.
Specifica un formato
Puoi fornire un format
opzionale argomento per specificare il formato della stringa data/ora fornita. La specifica del formato può essere qualsiasi stringa letterale, contenente 0 o più identificatori di formato.
Il format
parametro è disponibile da MongoDB versione 4.0.
Il formato predefinito è %Y-%m-%dT%H:%M:%S.%LZ
, che è ciò che utilizza l'esempio precedente.
Supponiamo di inserire il seguente documento nella nostra raccolta:
{ "_id" : 4, "bar" : "07/08/2020" }
In questo caso, la data potrebbe essere il 7° giorno dell'8° mese o l'8° giorno del 7° mese, a seconda della località utilizzata.
Possiamo usare una specifica di formato per specificare esattamente quale dovrebbe essere.
Esempio:
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%m/%d/%Y"
}
}
}
}
])
Risultato:
{ "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") }
In questo caso, abbiamo specificato che è l'8° giorno del 7° mese.
Eccolo di nuovo, ma questa volta scambiamo giorno e mese.
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%d/%m/%Y"
}
}
}
}
])
Risultato:
{ "_id" : 4, "date" : ISODate("2020-08-07T00:00:00Z") }
Questa volta viene interpretato come il 7° giorno dell'8° mese.
Vedi MongoDB $dateFromString
Identificatori di formato per un elenco di identificatori di formato validi.
Formato della data della settimana ISO
Esistono alcuni identificatori di formato che consentono di specificare le date utilizzando il formato ISO 8601.
In particolare, puoi utilizzare:
Specificatore di formato | Uscita |
---|---|
%G | Anno in formato ISO 8601 |
%u | Numero del giorno della settimana in formato ISO 8601 (1-lunedì, 7-domenica) |
%V | Settimana dell'anno in formato ISO 8601 |
Supponiamo di avere un documento simile a questo:
{ "_id" : 5, "bar" : "7-8-2020" }
Potremmo interpretare quella data come il 7° giorno della settimana ISO, seguito dall'8° settimana ISO dell'anno, seguito dall'anno.
In questo modo:
db.foo.aggregate([
{ $match: { _id: 5 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%u-%V-%G"
}
}
}
}
])
Risultato:
{ "_id" : 5, "date" : ISODate("2020-02-23T00:00:00Z") }
Specifica un fuso orario
Puoi specificare un fuso orario da utilizzare con $dateFromString
operatore.
Il fuso orario può essere specificato utilizzando l'identificatore del fuso orario Olson (ad es. "Europe/London"
, "GMT"
) o l'offset UTC (ad es. "+02:30"
, "-1030"
).
Identificatore di fuso orario Olson
Ecco un esempio che restituisce la stringa della data in tre diversi fusi orari, ciascuno dei quali utilizza gli ID fuso orario 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()
Risultato:
{ "_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") }
Offset UTC
Ecco un esempio che utilizza l'offset 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()
Risultato:
{ "_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") }
Se utilizzi il timezone
parametro, la stringa di data non può essere aggiunta con una Z per indicare l'ora Zulu (fuso orario UTC). Ad esempio, la stringa della data non può essere 2020-12-31T23:30:25.123Z
quando si utilizza il parametro fuso orario.
Inoltre, non includere le informazioni sul fuso orario nella stringa della data quando si utilizza il parametro del fuso orario.
Il onNull
Parametro
Il onNull
il parametro può essere utilizzato per specificare cosa restituire se la data è nulla o non esiste.
Il valore fornito a onNull
parametro può essere qualsiasi espressione valida.
Supponiamo di avere un documento come questo:
{ "_id" : 6, "bar" : null }
Potremmo usare onNull
nel modo seguente:
db.foo.aggregate([
{ $match: { _id: 6 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onNull: "No valid date was supplied"
}
}
}
}
])
Risultato:
{ "_id" : 6, "date" : "No valid date was supplied" }
In questo caso, la data era null
e quindi il documento di output include la stringa che ho fornito per onNull
parametro.
Il onError
Parametro
Puoi opzionalmente utilizzare il onError
parametro per fornire un'espressione da generare in caso di errore.
Supponiamo che la nostra collezione contenga il seguente documento:
{ "_id" : 7, "bar" : "21st Dec, 2030" }
Anche se c'è una data nella bar
campo, non è una stringa di data/ora valida e pertanto causerà un errore se utilizziamo dateFromString
per provare a convertirlo in un oggetto data.
Esempio di errore:
db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Risultato:
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
È un brutto errore.
Possiamo usare onError
parametro per renderlo più bello:
db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onError: "An error occurred while parsing the date string"
}
}
}
}
])
Risultato:
{ "_id" : 7, "date" : "An error occurred while parsing the date string" }
Visto come onNull
e onError
i parametri ci consentono di restituire i documenti effettivi, ci consentono di restituire più documenti, senza preoccuparci che un documento difettoso interrompa l'intera operazione.
Esempio:
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"
}
}
}
}
])
Risultato:
{ "_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" }