W MongoDB $rand Operator potoku agregacji zwraca losową liczbę zmiennoprzecinkową z zakresu od 0 do 1.
Wartość zmiennoprzecinkowa ma do 17 cyfr po przecinku. Wszelkie końcowe zera są usuwane, więc liczba cyfr może się różnić.
$rand operator został wprowadzony w MongoDB 4.4.2.
Przykład
Załóżmy, że mamy kolekcję o nazwie cats z następującymi dokumentami:
{ "_id" : 1, "name" : "Scratch" }
{ "_id" : 2, "name" : "Meow" }
{ "_id" : 3, "name" : "Fluffy" }
Możemy użyć $rand operator do wygenerowania losowej liczby dla każdego kota:
db.cats.aggregate(
[
{
$project:
{
randomNumber: { $rand: {} }
}
}
]
) Wynik:
{ "_id" : 1, "randomNumber" : 0.5593964875463812 }
{ "_id" : 2, "randomNumber" : 0.04357301703691149 }
{ "_id" : 3, "randomNumber" : 0.7556877215199272 }
$rand operator nie przyjmuje żadnych argumentów – po prostu wywołujesz go za pomocą $rand: {} .
Również $rand generuje nowy numer przy każdym wywołaniu. Dlatego wielokrotne uruchomienie powyższego kodu spowoduje wygenerowanie innej liczby losowej dla każdego kota.
Aby to zademonstrować, uruchomię go ponownie i oto nowy wynik:
{ "_id" : 1, "randomNumber" : 0.19672627212049873 }
{ "_id" : 2, "randomNumber" : 0.05513133909795318 }
{ "_id" : 3, "randomNumber" : 0.7509841462815067 } Widzimy, że liczby losowe różnią się od tych wygenerowanych w poprzednim przykładzie.
Liczby losowe większe niż 1
Jak wspomniano, $rand zwraca losową liczbę zmiennoprzecinkową między 0 a 1. Jest to w porządku, jeśli nie mamy nic przeciwko uzyskaniu zera, po którym następuje do 17 losowych miejsc po przecinku.
Ale co, jeśli chcemy losowej liczby większej niż 1?
W takich przypadkach możemy użyć $multiply operator do pomnożenia wyniku $rand .
Przykład:
db.cats.aggregate(
[
{
$project:
{
randomNumber: { $multiply: [ { $rand: {} }, 10 ] }
}
}
]
) Wynik:
{ "_id" : 1, "randomNumber" : 1.958938543288535 }
{ "_id" : 2, "randomNumber" : 4.437057321655847 }
{ "_id" : 3, "randomNumber" : 8.238909118372334 } Losowa liczba całkowita
Możemy również chcieć pozbyć się części ułamkowej. W tym przypadku możemy użyć operatora takiego jak $floor aby usunąć część dziesiętną, pozostawiając liczbę całkowitą.
Przykład:
db.cats.aggregate(
[
{
$project:
{
name: 1,
randomNumber: {
$floor: {
$multiply: [ { $rand: {} }, 10 ]
}
}
}
}
]
) Wynik:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 0 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 5 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 7 } I znowu, ale tym razem mnożymy to przez 100:
db.cats.aggregate(
[
{
$project:
{
name: 1,
randomNumber: {
$floor: {
$multiply: [ { $rand: {} }, 100 ]
}
}
}
}
]
) Wynik:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 18 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 62 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 92 } Zapisz wyniki
Jak wspomniano, $rand generuje nowy losowy zmiennoprzecinkowy przy każdym wywołaniu. Jest to w porządku, jeśli chcemy uzyskać nową liczbę losową za każdym razem, gdy uruchamiamy kod, ale co, jeśli chcemy przechowywać liczbę losową w każdym dokumencie?
Aby zapisać losową liczbę w dokumencie, możemy użyć $addFields operator (lub jego alias $set ), aby dodać nowe pole do dokumentu.
Przykład:
db.cats.aggregate(
[
{ $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } },
{ $set: { randomNumber: { $floor: "$randomNumber" } } },
{ $merge: "cats" }
]
)
W tym przykładzie dzielimy operację na dwa $set etapy i $merge scena.
$merge stage zapisuje wyniki potoku agregacji do określonej kolekcji i musi to być ostatni etap potoku.
Teraz, gdy zwracamy dokumenty z tej kolekcji (np. za pomocą metody takiej jak find() ), widzimy, że każdy dokument zawiera nowe pole z losową liczbą:
db.cats.find() Wynik:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 } Teraz liczba losowa jest trwała. Możemy zwracać dokumenty tyle razy, ile chcemy, a liczba losowa pozostanie taka sama.
Uruchommy find() ponownie:
db.cats.find() Wynik:
{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 } Dokładnie ta sama liczba losowa.