Dans MongoDB, le $rand
l'opérateur de pipeline d'agrégation renvoie un flottant aléatoire entre 0 et 1.
La valeur en virgule flottante comporte jusqu'à 17 chiffres après la virgule décimale. Tous les zéros à droite sont supprimés, le nombre de chiffres peut donc varier.
Le $rand
L'opérateur a été introduit dans MongoDB 4.4.2.
Exemple
Supposons que nous ayons une collection appelée cats
avec les documents suivants :
{ "_id" :1, "name" :"Scratch" }{ "_id" :2, "name" :"Meow" }{ "_id" :3, "name" :"Fluffy" }Nous pouvons utiliser le
$rand
opérateur pour générer un nombre aléatoire pour chaque chat :db.cats.aggregate( [ { $project: { randomNumber: { $rand: {} } } } ] )
Résultat :
{ "_id" :1, "randomNumber" :0.5593964875463812 }{ "_id" :2, "randomNumber" :0.04357301703691149 }{ "_id" :3, "randomNumber" :0.7556877215199272 }Le
$rand
L'opérateur n'accepte aucun argument - vous l'appelez simplement en utilisant$rand: {}
.Aussi,
$rand
génère un nouveau numéro à chaque appel. Par conséquent, exécuter le code ci-dessus plusieurs fois produira un nombre aléatoire différent pour chaque chat.Juste pour démontrer cela, je vais le relancer et voici le nouveau résultat :
{ "_id" :1, "randomNumber" :0.19672627212049873 }{ "_id" :2, "randomNumber" :0.05513133909795318 }{ "_id" :3, "randomNumber" :0.7509841462815067 }Nous pouvons voir que les nombres aléatoires sont différents de ceux générés dans l'exemple précédent.
Nombres aléatoires supérieurs à 1
Comme mentionné,
$rand
renvoie un flottant aléatoire entre 0 et 1. C'est bien si cela ne nous dérange pas d'obtenir un zéro, suivi d'un maximum de 17 décimales aléatoires.Mais que se passe-t-il si nous voulons un nombre aléatoire supérieur à 1 ?
Dans de tels cas, nous pouvons utiliser le
$multiply
opérateur pour multiplier le résultat de$rand
.Exemple :
db.cats.aggregate( [ { $project: { randomNumber: { $multiply: [ { $rand: {} }, 10 ] } } } ] )
Résultat :
{ "_id" :1, "randomNumber" :1.958938543288535 }{ "_id" :2, "randomNumber" :4.437057321655847 }{ "_id" :3, "randomNumber" :8.238909118372334 }Entier aléatoire
Nous pourrions également vouloir supprimer la partie fractionnaire. Dans ce cas, nous pouvons utiliser un opérateur tel que
$floor
pour supprimer la partie décimale, laissant donc un entier.Exemple :
db.cats.aggregate( [ { $project: { name: 1, randomNumber: { $floor: { $multiply: [ { $rand: {} }, 10 ] } } } } ] )
Résultat :
{ "_id" :1, "name" :"Scratch", "randomNumber" :0 }{ "_id" :2, "name" :"Meow", "randomNumber" :5 }{ "_id" :3, "name" :"Fluffy", "randomNumber" :7 }Le voici à nouveau, mais cette fois nous le multiplions par 100 :
db.cats.aggregate( [ { $project: { name: 1, randomNumber: { $floor: { $multiply: [ { $rand: {} }, 100 ] } } } } ] )
Résultat :
{ "_id" :1, "name" :"Scratch", "randomNumber" :18 }{ "_id" :2, "name" :"Meow", "randomNumber" :62 }{ "_id" :3, "name" :"Fluffy", "randomNumber" :92 }Enregistrer les résultats
Comme mentionné,
$rand
génère un nouveau flottant aléatoire à chaque fois qu'il est appelé. C'est bien si nous voulons un nouveau nombre aléatoire à chaque fois que nous exécutons le code, mais que se passe-t-il si nous voulons stocker le nombre aléatoire dans chaque document ?Pour stocker le nombre aléatoire dans le document, nous pouvons utiliser le
$addFields
opérateur (ou son alias$set
) pour ajouter le nouveau champ au document.Exemple :
db.cats.aggregate( [ { $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } }, { $set: { randomNumber: { $floor: "$randomNumber" } } }, { $merge: "cats" } ] )
Dans cet exemple, nous séparons l'opération sur deux
$set
étapes et un$merge
organiser.Le
$merge
stage écrit les résultats du pipeline d'agrégation dans une collection spécifiée, et il doit s'agir de la dernière étape du pipeline.Maintenant, lorsque nous renvoyons les documents de cette collection (par exemple en utilisant une méthode comme
find()
), nous pouvons voir que chaque document contient le nouveau champ avec le nombre aléatoire :db.cats.find()
Résultat :
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, "name" :"Fluffy", "randomNumber" :73 }Maintenant, le nombre aléatoire est persistant. Nous pouvons retourner les documents autant de fois que nous le souhaitons, et le nombre aléatoire restera le même.
Exécutons
find()
encore :db.cats.find()
Résultat :
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, "name" :"Fluffy", "randomNumber" :73 }Exactement le même nombre aléatoire.