MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB $dateFromString

Dans MongoDB, le $dateFromString l'opérateur de pipeline d'agrégation convertit une chaîne date/heure en objet date.

Exemple

Supposons que nous ayons une collection appelée foo avec les documents suivants :

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

Tous les documents contiennent une chaîne date/heure.

Nous pouvons exécuter le code suivant pour renvoyer un objet date à partir de la bar champs dans ces documents.

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

Résultat :

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

Toutes les chaînes de date/heure ont été converties en un objet date.

J'ai également changé le nom du champ de bar à date .

Spécifier un format

Vous pouvez fournir un format facultatif argument pour spécifier le format de la chaîne de date/heure qui est fournie. La spécification de format peut être n'importe quel littéral de chaîne, contenant 0 ou plusieurs spécificateurs de format.

Le format le paramètre est disponible à partir de la version 4.0 de MongoDB.

Le format par défaut est %Y-%m-%dT%H:%M:%S.%LZ , qui est ce que l'exemple précédent utilise.

Supposons que nous insérions le document suivant dans notre collection :

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

Dans ce cas, la date peut être le 7e jour du 8e mois ou le 8e jour du 7e mois, selon les paramètres régionaux utilisés.

Nous pouvons utiliser une spécification de format pour spécifier exactement lequel il doit s'agir.

Exemple :

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

Résultat :

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

Dans ce cas, nous avons précisé qu'il s'agit du 8e jour du 7e mois.

Le voici à nouveau, mais cette fois, nous échangeons le jour et le mois.

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

Résultat :

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

Cette fois, il est interprété comme le 7e jour du 8e mois.

Voir MongoDB $dateFromString Spécificateurs de format pour une liste de spécificateurs de format valides.

Format de date de la semaine ISO

Il existe quelques spécificateurs de format qui vous permettent de spécifier des dates en utilisant le format ISO 8601.

Vous pouvez notamment utiliser :

Spécificateur de format Sortie
%G Année au format ISO 8601
%u Numéro du jour de la semaine au format ISO 8601 (1-lundi, 7-dimanche)
%V Semaine de l'année au format ISO 8601

Supposons que nous ayons un document qui ressemble à ceci :

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

Nous pourrions interpréter cette date comme étant le 7ème jour de la semaine ISO, suivi de la 8ème semaine ISO de l'année, suivi de l'année.

Comme ceci :

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

Résultat :

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

Spécifiez un fuseau horaire

Vous pouvez spécifier un fuseau horaire à utiliser avec le $dateFromString opérateur.

Le fuseau horaire peut être spécifié à l'aide de l'identifiant de fuseau horaire Olson (par exemple, "Europe/London" , "GMT" ) ou le décalage UTC (par exemple "+02:30" , "-1030" ).

Identifiant de fuseau horaire Olson

Voici un exemple qui génère la chaîne de date dans trois fuseaux horaires différents, chacun utilisant les ID de fuseau horaire 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()

Résultat :

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

Décalage UTC

Voici un exemple qui utilise le décalage 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()

Résultat :

{
	"_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 vous utilisez le timezone paramètre, la chaîne de date ne peut pas être ajoutée avec un Z pour indiquer l'heure zoulou (fuseau horaire UTC). Par exemple, la chaîne de date ne peut pas être 2020-12-31T23:30:25.123Z lors de l'utilisation du paramètre de fuseau horaire.

De plus, n'incluez pas les informations de fuseau horaire dans la chaîne de date lorsque vous utilisez le paramètre de fuseau horaire.

Le onNull Paramètre

Le onNull Le paramètre peut être utilisé pour spécifier ce qu'il faut retourner si la date est nulle ou n'existe pas.

La valeur fournie au onNull le paramètre peut être n'importe quelle expression valide.

Supposons que nous ayons un document comme celui-ci :

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

Nous pourrions utiliser onNull de la manière suivante :

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

Résultat :

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

Dans ce cas, la date était null et donc le document de sortie inclut la chaîne que j'ai fournie pour le onNull paramètre.

Le onError Paramètre

Vous pouvez éventuellement utiliser le onError paramètre pour fournir une expression à afficher en cas d'erreur.

Supposons que notre collection contienne le document suivant :

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

Même s'il y a une date dans la bar champ, ce n'est pas une chaîne de date/heure valide, et cela provoquera donc une erreur si nous utilisons dateFromString pour essayer de le convertir en objet date.

Exemple d'erreur :

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

Résultat :

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

C'est une mauvaise erreur.

Nous pouvons utiliser le onError paramètre pour le rendre plus joli :

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

Résultat :

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

Vu comme le onNull et onError nous permettent de renvoyer les documents réels, ils nous permettent de renvoyer plusieurs documents, sans se soucier d'un mauvais document interrompant toute l'opération.

Exemple :

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

Résultat :

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