In MongoDB der $rand
Der Aggregations-Pipeline-Operator gibt eine zufällige Gleitkommazahl zwischen 0 und 1 zurück.
Der Fließkommawert hat bis zu 17 Nachkommastellen. Nachgestellte Nullen werden weggelassen, daher kann die Anzahl der Ziffern variieren.
Der $rand
-Operator wurde in MongoDB 4.4.2 eingeführt.
Beispiel
Angenommen, wir haben eine Sammlung namens cats
mit folgenden Dokumenten:
{ "_id" :1, "name" :"Scratch" }{ "_id" :2, "name" :"Miau" }{ "_id" :3, "name" :"Fluffy" }Wir können den
$rand
verwenden Operator, um eine Zufallszahl für jede Katze zu generieren:db.cats.aggregate( [ { $project: { randomNumber: { $rand: {} } } } ] )
Ergebnis:
{ "_id" :1, "randomNumber" :0.5593964875463812 }{ "_id" :2, "randomNumber" :0.04357301703691149 }{ "_id" :3, "randomNumber" :0.7556877215199272 }Der
$rand
Der Operator akzeptiert keine Argumente – Sie rufen ihn einfach mit$rand: {}
auf .Auch
$rand
generiert bei jedem Anruf eine neue Nummer. Wenn Sie den obigen Code also mehrmals ausführen, wird für jede Katze eine andere Zufallszahl erzeugt.Nur um dies zu demonstrieren, führe ich es erneut aus und hier ist das neue Ergebnis:
{ "_id" :1, "randomNumber" :0.19672627212049873 }{ "_id" :2, "randomNumber" :0.05513133909795318 }{ "_id" :3, "randomNumber" :0.7509841462815067 }Wir können sehen, dass sich die Zufallszahlen von denen unterscheiden, die im vorherigen Beispiel generiert wurden.
Zufallszahlen größer als 1
Wie bereits erwähnt,
$rand
gibt einen zufälligen Float zwischen 0 und 1 zurück. Das ist in Ordnung, wenn es uns nichts ausmacht, eine Null zu bekommen, gefolgt von bis zu 17 zufälligen Dezimalstellen.Aber was ist, wenn wir eine Zufallszahl größer als 1 wollen?
In solchen Fällen können wir den
$multiply
verwenden Operator, um das Ergebnis von$rand
zu multiplizieren .Beispiel:
db.cats.aggregate( [ { $project: { randomNumber: { $multiply: [ { $rand: {} }, 10 ] } } } ] )
Ergebnis:
{ "_id" :1, "randomNumber" :1.958938543288535 }{ "_id" :2, "randomNumber" :4.437057321655847 }{ "_id" :3, "randomNumber" :8.238909118372334 }Zufallszahl
Vielleicht möchten wir auch den Bruchteil abschaffen. In diesem Fall können wir einen Operator wie
$floor
verwenden um den Dezimalteil zu entfernen, wodurch eine ganze Zahl übrig bleibt.Beispiel:
db.cats.aggregate( [ { $project: { name: 1, randomNumber: { $floor: { $multiply: [ { $rand: {} }, 10 ] } } } } ] )
Ergebnis:
{ "_id" :1, "name" :"Scratch", "randomNumber" :0 }{ "_id" :2, "name" :"Miau", "randomNumber" :5 }{ "_id" :3, „name“ :„Fluffy“, „randomNumber“ :7 }Hier ist es wieder, aber diesmal multiplizieren wir es mit 100:
db.cats.aggregate( [ { $project: { name: 1, randomNumber: { $floor: { $multiply: [ { $rand: {} }, 100 ] } } } } ] )
Ergebnis:
{ "_id" :1, "name" :"Scratch", "randomNumber" :18 }{ "_id" :2, "name" :"Meow", "randomNumber" :62 }{ "_id" :3, „name“ :„Fluffy“, „randomNumber“ :92 }Speichern Sie die Ergebnisse
Wie bereits erwähnt,
$rand
generiert bei jedem Aufruf einen neuen zufälligen Float. Das ist in Ordnung, wenn wir jedes Mal, wenn wir den Code ausführen, eine neue Zufallszahl wollen, aber was, wenn wir die Zufallszahl in jedem Dokument speichern wollen?Um die Zufallszahl im Dokument zu speichern, können wir die
$addFields
verwenden Operator (oder sein Alias $set
), um das neue Feld zum Dokument hinzuzufügen.Beispiel:
db.cats.aggregate( [ { $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } }, { $set: { randomNumber: { $floor: "$randomNumber" } } }, { $merge: "cats" } ] )
In diesem Beispiel trennen wir die Operation über zwei
$set
Stages und ein$merge
Bühne.Der
$merge
stage schreibt die Ergebnisse der Aggregationspipeline in eine angegebene Sammlung und muss die letzte Stufe in der Pipeline sein.Wenn wir nun die Dokumente aus dieser Sammlung zurückgeben (z. B. mit einer Methode wie
find()
), können wir sehen, dass jedes Dokument das neue Feld mit der Zufallszahl enthält:db.cats.find()
Ergebnis:
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, „name“ :„Fluffy“, „randomNumber“ :73 }Jetzt ist die Zufallszahl persistent. Wir können die Dokumente beliebig oft zurücksenden, und die Zufallszahl bleibt gleich.
Lassen Sie uns
find()
ausführen nochmal:db.cats.find()
Ergebnis:
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, „name“ :„Fluffy“, „randomNumber“ :73 }Genau die gleiche Zufallszahl.