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

Introduction aux types de données MongoDB


Introduction

Lorsque vous utilisez MongoDB, vous avez la possibilité d'être flexible avec la structure de vos données. Vous n'êtes pas obligé de maintenir un certain schéma dans lequel tous vos documents doivent s'inscrire. Pour n'importe quel champ donné dans un document, vous pouvez utiliser n'importe lequel des types de données disponibles pris en charge par MongoDB. Malgré cette méthode de travail par défaut, vous pouvez imposer un schéma JSON dans MongoDB pour ajouter une validation à vos collections si vous le souhaitez. Nous n'entrerons pas dans les détails de la conception du schéma dans ce guide, mais cela peut avoir un effet sur le typage des données s'il est implémenté.

Les types de données spécifient un modèle général pour les données qu'ils acceptent et stockent. Il est primordial de comprendre quand choisir un certain type de données plutôt qu'un autre lors de la planification de votre base de données. Le type choisi va dicter comment vous pouvez opérer sur vos données et comment elles sont stockées.



JSON et BSON

Avant d'entrer dans les détails de types de données spécifiques, il est important de comprendre comment MongoDB stocke les données. MongoDB et de nombreuses autres bases de données NoSQL basées sur des documents utilisent JSON (JavaScript Object Notation) pour représenter les enregistrements de données sous forme de documents.

L'utilisation de JSON pour stocker des données présente de nombreux avantages. Certains d'entre eux étant :

  • la facilité à lire, à apprendre et sa familiarité avec les développeurs
  • flexibilité du format, qu'il soit clairsemé, hiérarchique ou profondément imbriqué
  • auto-descriptif, qui permet aux applications de fonctionner facilement avec des données JSON
  • permet de se concentrer sur un nombre minimal de types de base

JSON prend en charge tous les types de données de base tels que chaîne, nombre, booléen, etc. MongoDB stocke en fait les enregistrements de données sous forme de documents JSON codés en binaire (BSON). Comme JSON, BSON prend en charge l'intégration de documents et de tableaux dans d'autres documents et tableaux. BSON autorise des types de données supplémentaires qui ne sont pas disponibles pour JSON.



Quels sont les types de données dans MongoDB ?

Avant d'entrer dans les détails, examinons les types de données pris en charge dans MongoDB.

MongoDB prend en charge une gamme de types de données adaptés à divers types de données simples et complexes. Ceux-ci incluent :

Texte

  • String

Numérique

  • 32-Bit Integer
  • 64-Bit Integer
  • Double
  • Decimal128

Date/Heure

  • Date
  • Timestamp

Autre

  • Object
  • Array
  • Binary Data
  • ObjectId
  • Boolean
  • Null
  • Regular Expression
  • JavaScript
  • Min Key
  • Max Key

Dans MongoDB, chaque type BSON a à la fois un entier et des identifiants de chaîne. Nous aborderons plus en détail les plus courants d'entre eux tout au long de ce guide.



Types de chaînes

Le type de chaîne est le type de données MongoDB le plus couramment utilisé. Toute valeur écrite entre guillemets doubles "" dans JSON est une valeur de chaîne. Toute valeur que vous souhaitez stocker sous forme de texte sera mieux saisie sous forme de String . Les chaînes BSON sont UTF-8 et sont représentées dans MongoDB comme :

        Type         | Number |  Alias   |  ------------------ | ------ | -------- |       String        |    2   | "string" |

Généralement, les pilotes des langages de programmation convertissent le format de chaîne du langage en UTF-8 lors de la sérialisation et de la désérialisation de BSON. Cela fait de BSON une méthode attrayante pour stocker facilement des caractères internationaux, par exemple.

Insérer un document avec une String le type de données ressemblera à ceci :

db.mytestcoll.insertOne({first_name: "Alex"}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d15")}

L'interrogation de la collection renverra ce qui suit :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d15"),         first_name: "Alex"}

Utilisation du $type opérateur

Avant de passer à notre prochain type de données, il est important de savoir comment vous pouvez taper vérifier la valeur avant de faire des insertions. Nous utiliserons l'exemple précédent pour démontrer l'utilisation du $type opérateur dans MongoDB.

Disons que cela fait un moment que nous n'avons pas travaillé avec le mytestcoll collecte d'avant. Nous voulons insérer des documents supplémentaires dans la collection avec le first_name domaine. Pour vérifier que nous avons utilisé String comme type de données stocké comme valeur de first_name à l'origine, nous pouvons exécuter ce qui suit en utilisant l'alias ou la valeur numérique du type de données :

db.mytestcoll.find( { "first_name": { $type: "string" } } )

Ou

db.mytestcoll.find( { "first_name": { $type: 2 } } )

Les deux requêtes renvoient une sortie de tous les documents qui ont une String valeur stockée pour first_name de l'insertion de notre section précédente :

[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]

Si vous recherchez un type qui n'est pas stocké dans le first_name champ de n'importe quel document, vous n'obtiendrez aucun résultat. Cela indique qu'il s'agit d'un autre type de données stocké dans first_name .

Vous pouvez également interroger plusieurs types de données à la fois avec le $type opérateur comme le suivant :

db.mytestcoll.find( { "first_name": { $type: ["string", "null"] } } )

Parce que nous n'avons pas inséré de Null saisissez des valeurs dans notre collection, le résultat sera le même :

[ { _id: ObjectId("614b37296a124db40ae74d15"), first_name: "Alex" } ]

Vous pouvez utiliser la même méthode avec tous les types suivants dont nous parlerons.




Nombres et valeurs numériques

MongoDB comprend une gamme de types de données numériques adaptés à différents scénarios. Le choix du type à utiliser dépend de la nature des valeurs que vous prévoyez de stocker et de vos cas d'utilisation des données. JSON appelle n'importe quoi avec des nombres un Numéro . Cela oblige le système à trouver comment le transformer en type de données natif le plus proche. Nous commencerons par explorer les entiers et leur fonctionnement dans MongoDB.


Entier

Le Integer Le type de données est utilisé pour stocker des nombres sous forme de nombres entiers sans fractions ni décimales. Les entiers peuvent être des valeurs positives ou négatives. Il existe deux types dans MongoDB, 32-Bit Integer et 64-Bit Integer . Ils peuvent être représentés des deux manières décrites dans le tableau ci-dessous, number et alias :

  Integer type   | number |    alias     |   ------------   | -----  | ------------ |  `32-bit integer`|   16   |    "int"     | `64-bit integer`|   18   |    "long"    |

Les plages dans lesquelles une valeur peut s'inscrire pour chaque type sont les suivantes :

  Integer type   |    Applicable signed range     |    Applicable unsigned range    |  ------------   | ------------------------------ | ------------------------------- | `32-bit integer`| -2,147,483,648 to 2,147,483,647|  0 to 4,294,967,295             | `64-bit integer`| -9,223,372,036,854,775,808 to  |  0 to 18,446,744,073,709,551,615                         9,223,372,036,854,775,807

Les types ci-dessus sont limités par leur plage valide. Toute valeur en dehors de la plage entraînera une erreur. Insertion d'un Integer saisir dans MongoDB ressemblera à ceci :

db.mytestcoll.insertOne({age: 26}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d14")}

Et trouver le résultat renverra ce qui suit :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"), age: 26}

Comme suggéré par les noms, un 32-Bit Integer a 32 bits de précision entière, ce qui est utile pour les valeurs entières plus petites que vous ne souhaitez pas stocker sous forme de séquence de chiffres. Lorsque la taille du nombre augmente, vous pouvez passer à l'64-Bit Integer qui a une précision entière de 64 bits et correspond au même cas d'utilisation que le précédent.



Double

Dans BSON, le remplacement par défaut du numéro de JSON est le Double Type de données. Le Double Le type de données est utilisé pour stocker une valeur à virgule flottante et peut être représenté dans MongoDB comme suit :

        Type         | Number |   Alias  |  ------------------ | ------ | -------- |       Double        |    1   | "double" |

Les nombres à virgule flottante sont une autre façon d'exprimer les nombres décimaux, mais sans précision exacte et cohérente.

Les nombres à virgule flottante peuvent fonctionner efficacement avec un grand nombre de décimales, mais pas toujours exactement. Voici un exemple de saisie d'un document avec le Double tapez dans votre collection :

db.mytestcoll.insertOne({testScore: 89.6}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d13")}

Il peut y avoir de légères différences entre l'entrée et la sortie lors du calcul avec des doubles qui pourraient potentiellement conduire à un comportement inattendu. Lors de l'exécution d'opérations nécessitant des valeurs exactes, MongoDB a un type plus précis.



Decimal128

Si vous travaillez avec de très grands nombres avec beaucoup de plage à virgule flottante, alors le Decimal128 Le type de données BSON sera la meilleure option. Ce sera le type le plus utile pour les valeurs qui nécessitent beaucoup de précision comme dans les cas d'utilisation impliquant des opérations monétaires exactes. Le Decimal128 le type est représenté par :

        Type         | Number |   Alias   |  ------------------ | ------ | --------- |      Decimal128     |   19   | "decimal" |

Le type BSON, Decimal128 , fournit 128 bits de représentation décimale pour stocker des nombres où l'arrondi exact des décimales est important. Decimal128 prend en charge 34 chiffres décimaux de précision, ou un sinificande avec une plage de -6143 à +6144. Cela permet une grande précision.

Insertion d'une valeur à l'aide du Decimal128 le type de données nécessite l'utilisation de NumberDecimal() constructeur avec votre numéro comme String pour empêcher MongoDB d'utiliser le type numérique par défaut, Double .

Ici, nous démontrons ceci :

db.mytestcoll.insertOne({price : NumberDecimal("5.099")}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d12")}

Lors de l'interrogation de la collection, vous obtenez alors le retour suivant :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d12"),         price: "5.099" }

La valeur numérique conserve sa précision permettant des opérations exactes. Pour démontrer le Decimal128 type versus le Double , nous pouvons faire l'exercice suivant.



Comment la précision peut être perdue en fonction du type de données

Disons que nous voulons insérer un nombre avec de nombreuses valeurs décimales en tant que Double dans MongoDB avec ce qui suit :

db.mytestcoll.insertOne({ price: 9999999.4999999999 }){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d24")}

Lorsque nous interrogeons ces données, nous obtenons le résultat suivant :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d24"),         price: 9999999.5}

Cette valeur est arrondie à 9999999.5 , perdant sa valeur exacte avec laquelle nous l'avons saisie. Cela fait Double mal adapté au stockage de nombres avec de nombreuses décimales.

L'exemple suivant montre où la précision sera perdue lors du passage d'un Double implicitement avec Decimal128 au lieu d'une String comme dans l'exemple précédent.

On commence par insérer le Double suivant encore mais avec NumberDecimal() pour en faire un Decimal128 saisissez :

db.mytestcoll.insertOne({ price: NumberDecimal( 9999999.4999999999 ) }){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d14")}

Remarque :Lors de cette insertion dans le shell MongoDB, le message d'avertissement suivant s'affiche :

Warning: NumberDecimal: specifying a number as argument is deprecated and may lead to loss of precision, pass a string instead

Ce message d'avertissement indique que le nombre que vous essayez de passer pourrait être sujet à une perte de précision. Ils suggèrent d'utiliser une String en utilisant NumberDecimal() afin que vous ne perdiez aucune précision.

Si nous ignorons l'avertissement et insérons quand même le document, la perte de précision est visible dans les résultats de la requête en arrondissant la valeur :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"),         price: Decimal128("9999999.50000000")}

Si nous suivons le NumberDecimal() recommandé approche utilisant une String nous verrons les résultats suivants avec une précision maintenue :

db.mytestcoll.insertOne({ price: NumberDecimal( "9999999.4999999999" ) } )
db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d14"),         price: Decimal128("9999999.4999999999")}

Pour tout cas d'utilisation nécessitant des valeurs précises et exactes, ce retour pourrait causer des problèmes. Tout travail impliquant des opérations monétaires est un exemple où la précision va être extrêmement importante et avoir des valeurs exactes est essentiel pour des calculs précis. Cette démonstration souligne l'importance de savoir quel type de données numériques sera le mieux adapté à vos données.




Date

La Date du BSON Le type de données est un entier 64 bits qui représente le nombre de millisecondes depuis l'époque Unix (1er janvier 1970). Ce type de données stocke la date ou l'heure actuelle et peut être renvoyé sous la forme d'un objet date ou d'une chaîne. Date est représenté dans MongoDB comme suit :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |        Date         |    9   |     "date"   |

Remarque :BSON Date le type est signé. Les valeurs négatives représentent des dates antérieures à 1970.

Il existe trois méthodes pour renvoyer des valeurs de date.

  1. Date() - renvoie une chaîne

  2. new Date() - retourne un objet date en utilisant le ISODate() emballage

  3. ISODate() - renvoie également un objet date en utilisant le ISODate() emballage

Nous démontrons ces options ci-dessous :

var date1 = Date()var date2 = new Date()var date3 = ISODate()db.mytestcoll.insertOne({firstDate: date1, secondDate: date2, thirdDate: date3}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d22")}

Et au retour :

db.mytestcoll.find().pretty(){                "_id" : ObjectId("614b37296a124db40ae74d22"),                firstDate: 'Tue Sep 28 2021 11:28:52 GMT+0200 (Central European Summer Time)',                secondDate: ISODate("2021-09-28T09:29:01.924Z"),                thirdDate: ISODate("2021-09-28T09:29:12.151Z")}


Horodatage

Il y a aussi le Timestamp type de données dans MongoDB pour représenter le temps. Cependant, Timestamp va être plus utile pour un usage interne et ne l'est pas associé à la Date taper. Le type lui-même est une séquence de caractères utilisée pour décrire la date et l'heure auxquelles un événement se produit. Timestamp est une valeur 64 bits où :

  • les 32 bits les plus significatifs sont time_t valeur (secondes depuis l'époque Unix)
  • les 32 bits les moins significatifs sont un ordinal incrémenté pour les opérations dans une seconde donnée

Sa représentation dans MongoDB ressemblera à ceci :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      Timestamp      |   17   |  "timestamp" |

Lors de l'insertion d'un document contenant des champs de niveau supérieur avec des horodatages vides, MongoDB remplacera la valeur d'horodatage vide par la valeur d'horodatage actuelle. L'exception à cela est si le _id champ contient un horodatage vide. La valeur d'horodatage sera toujours insérée telle quelle et non remplacée.

Insertion d'un nouveau Timestamp la valeur dans MongoDB utilisera le new Timestamp() fonction et ressemble à ceci :

db.mytestcoll.insertOne( {ts: new Timestamp() });{        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d23")}

Lors de l'interrogation de la collection, vous renverrez un résultat semblable à :

db.mytestcoll.find().pretty(){        "_id" : ObjectId("614b37296a124db40ae74d24"),         "ts" : Timestamp( { t: 1412180887, i: 1 })}


Objet

L'Object Le type de données dans MongoDB est utilisé pour stocker les documents intégrés. Un document intégré est une série de documents imbriqués dans key: value forme de paire. Nous démontrons l'Object tapez ci-dessous :

var classGrades = {"Physics": 88, "German": 92, "LitTheoery": 79}db.mytestcoll.insertOne({student_name: "John Smith", report_card: classGrades}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d18")}

Nous pouvons alors visualiser notre nouveau document :

db.mytestcoll.find().pretty(){    _id: ObjectId("614b37296a124db40ae74d18"),    student_name: 'John Smith',    report_card: {Physics: 88, German: 92, LitTheoery: 79}}

L'Object Le type de données optimise le stockage des données auxquelles il est préférable d'accéder ensemble. Il offre des gains d'efficacité en matière de stockage, de vitesse et de durabilité, par opposition au stockage séparé de chaque marque de classe de l'exemple ci-dessus.



Données binaires

Les Binary Data , ou BinData , le type de données fait exactement ce que son nom implique et stocke des données binaires pour la valeur d'un champ. BinData est mieux utilisé lorsque vous stockez et recherchez des données, en raison de son efficacité dans la représentation des tableaux de bits. Ce type de données peut être représenté des manières suivantes :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      Binary data    |    5   |   "binData"  |

Voici un exemple d'ajout de quelques Binary Data dans un document d'une collection :

var data = BinData(1, "111010110111100110100010101")db.mytestcoll.insertOne({binaryData: data}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d20")}

Pour voir ensuite le document résultant :

db.mytestcoll.find().pretty(){        "_id" : ObjectId("614b37296a124db40ae74d20"),        "binaryData" : BinData(1, "111010110111100110100010101")}


ObjectId

L'ObjectId type est spécifique à MongoDB et il stocke l'ID unique du document. MongoDB fournit un _id champ pour chaque document. ObjectId a une taille de 12 octets et peut être représenté comme suit :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      ObjectId       |    7   |   "objectId" |

ObjectId se compose de trois parties qui composent sa composition de 12 octets :

  • une valeur d'horodatage de 4 octets , représentant la création de l'ObjectId, mesurée en secondes depuis l'époque Unix
  • une valeur aléatoire de 5 octets
  • un compteur d'incrémentation de 3 octets initialisé à une valeur aléatoire

Dans MongoDB, chaque document d'une collection nécessite un _id unique faire office de clé primaire. Si le _id champ est laissé vide pour un document inséré, MongoDB générera automatiquement un ObjectId pour le champ.

Il y a plusieurs avantages à utiliser ObjectIds pour le _id :

  • en mongosh (shell MongoDB), l'heure de création de l'ObjectId est accessible à l'aide de ObjectId.getTimestamp() méthode.
  • tri sur un _id champ qui stocke ObjectId types de données est un équivalent proche du tri par heure de création.

Jusqu'à présent, nous avons vu des ObjectIds dans les exemples, et ils ressembleront à ceci :

db.mytestcoll.find().pretty(){         _id: ObjectId("614b37296a124db40ae74d19")}

Remarque :Les valeurs ObjectId doivent augmenter avec le temps, mais elles ne sont pas nécessairement monotones. C'est parce qu'ils :

  • Ne contient qu'une seconde de résolution temporelle, de sorte que les valeurs créées dans la même seconde n'ont pas d'ordre garanti
  • les valeurs sont générées par les clients, qui peuvent avoir des horloges système différentes


Booléen

MongoDB a le Boolean natif type de données pour stocker les valeurs vraies et fausses dans une collection. Boolean dans MongoDB peut être représenté comme suit :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |       Boolean       |    8   |     "bool"   |

Insérer un document avec un Boolean le type de données ressemblera à ceci :

db.mytestcoll.insertOne({isCorrect: true, isIncorrect: false}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d21")}

Ensuite, lors de la recherche du document, le résultat apparaîtra comme :

db.mytestcoll.find().pretty(){    "_id" : ObjectId("614b37296a124db40ae74d21")    "isCorrect" : true,    "isIncorrect" : false}


Expression régulière

L'Regular Expression Le type de données dans MongoDB permet le stockage d'expressions régulières en tant que valeur d'un champ. MongoDB utilise PCRE (Perl Compatible Regular Expression) comme langage d'expression régulière.

Il peut être représenté de la manière suivante :

        Type         | Number |  Alias  |  ------------------ | ------ | ------- |  Regular Expression |   11   | "regex" |

BSON vous permet d'éviter l'étape typique de "convertir à partir d'une chaîne" qui est couramment rencontrée lorsque vous travaillez avec des expressions régulières et des bases de données. Ce type sera plus utile lorsque vous écrivez des objets de base de données qui nécessitent des modèles de validation ou des déclencheurs correspondants.

Par exemple, vous pouvez insérer l'Regular Expression type de données comme ceci :

db.mytestcoll.insertOne({exampleregex: /tt/}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d16")}db.mytestcoll.insertOne({exampleregext:/t+/}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d17")}

Cette séquence de déclarations ajoutera ces documents à votre collection. Vous pouvez alors interroger votre collection pour retrouver les documents insérés :

db.mytestcoll.find().pretty(){        _id: ObjectId("614b37296a124db40ae74d16"), exampleregex: /tt/,        _id: ObjectId("614b37296a124db40ae74d17"), exampleregex: /t+/ }

Les modèles d'expressions régulières sont stockés en tant que regex et non en tant que chaînes. Cela vous permet d'interroger une chaîne particulière et d'obtenir les documents renvoyés dont l'expression régulière correspond à la chaîne souhaitée.



JavaScript (sans portée)

Tout comme l'Regular Expression mentionnée précédemment type de données, BSON permet à MongoDB de stocker des fonctions JavaScript sans portée comme leur propre type. Le JavaScript le type peut être reconnu comme suit :

        Type         | Number |     Alias    |  ------------------ | ------ | ------------ |      JavaScript     |   13   | "javascript" |

Ajouter un document à votre collection avec le JavaScript le type de données ressemblera à ceci :

db.mytestcoll.insertOne({jsCode: "function(){var x; x=1}"}){        "acknowledged": true,        "insertedId": ObjectId("614b37296a124db40ae74d122")}

Cette fonctionnalité vous permet de stocker des fonctions JavaScript dans vos collections MongoDB si nécessaire pour un cas d'utilisation particulier.

Remarque :Avec MongoDB version 4.4 et supérieure, un type JavaScript alternatif, le JavaScript with Scope type de données, est obsolète



Conclusion

Dans cet article, nous avons couvert la plupart des types de données courants qui sont utiles lorsque vous travaillez avec des bases de données MongoDB. Il existe des types supplémentaires qui ne sont pas explicitement couverts dans ce guide et qui peuvent être utiles selon le cas d'utilisation. Commencer par connaître ces types couvre la plupart des cas d'utilisation. C'est une base solide pour commencer à modéliser votre base de données MongoDB.

Il est important de savoir quels types de données sont disponibles lorsque vous utilisez une base de données afin que vous utilisiez des valeurs valides et que vous utilisiez les données avec les résultats attendus. Il y a des risques que vous pouvez courir sans saisir correctement vos données comme démontré dans le Double contre Decimal128 exercer. Il est important d'y penser avant de s'engager dans un type donné.

Si vous souhaitez tester Prisma avec une base de données MongoDB, vous pouvez consulter la documentation du connecteur de données.