MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $dateFromString

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