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.
-
Date()
- renvoie une chaîne -
new Date()
- retourne un objet date en utilisant leISODate()
emballage -
ISODate()
- renvoie également un objet date en utilisant leISODate()
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 deObjectId.getTimestamp()
méthode. - tri sur un
_id
champ qui stockeObjectId
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.