MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $ randa

In MongoDB, il $rand l'operatore della pipeline di aggregazione restituisce un float casuale compreso tra 0 e 1.

Il valore in virgola mobile ha fino a 17 cifre dopo la virgola decimale. Eventuali zeri finali vengono eliminati, quindi il numero di cifre può variare.

Il $rand operatore è stato introdotto in MongoDB 4.4.2.

Esempio

Supponiamo di avere una collezione chiamata cats con i seguenti documenti:

{ "_id" : 1, "name" : "Scratch" }
{ "_id" : 2, "name" : "Meow" }
{ "_id" : 3, "name" : "Fluffy" }

Possiamo usare il $rand operatore per generare un numero casuale per ogni gatto:

db.cats.aggregate(
   [
     {
       $project:
          {
            randomNumber: { $rand: {} }
          }
     }
   ]
)

Risultato:

{ "_id" : 1, "randomNumber" : 0.5593964875463812 }
{ "_id" : 2, "randomNumber" : 0.04357301703691149 }
{ "_id" : 3, "randomNumber" : 0.7556877215199272 }

Il $rand l'operatore non accetta alcun argomento:lo chiami semplicemente usando $rand: {} .

Inoltre, $rand genera un nuovo numero ogni volta che viene chiamato. Pertanto, l'esecuzione del codice sopra più volte produrrà un numero casuale diverso per ogni cat.

Solo per dimostrarlo, lo eseguirò di nuovo ed ecco il nuovo risultato:

{ "_id" : 1, "randomNumber" : 0.19672627212049873 }
{ "_id" : 2, "randomNumber" : 0.05513133909795318 }
{ "_id" : 3, "randomNumber" : 0.7509841462815067 }

Possiamo vedere che i numeri casuali sono diversi da quelli generati nell'esempio precedente.

Numeri casuali maggiori di 1

Come accennato, $rand restituisce un float casuale compreso tra 0 e 1. Questo va bene se non ci dispiace ottenere uno zero, seguito da un massimo di 17 cifre decimali casuali.

Ma cosa succede se vogliamo un numero casuale maggiore di 1?

In questi casi, possiamo usare il $multiply operatore per moltiplicare il risultato di $rand .

Esempio:

db.cats.aggregate(
   [
     {
       $project:
          {
            randomNumber: { $multiply: [ { $rand: {} }, 10 ] }
          }
     }
   ]
)

Risultato:

{ "_id" : 1, "randomNumber" : 1.958938543288535 }
{ "_id" : 2, "randomNumber" : 4.437057321655847 }
{ "_id" : 3, "randomNumber" : 8.238909118372334 }

Intero casuale

Potremmo anche voler eliminare la parte frazionaria. In questo caso, possiamo usare un operatore come $floor per rimuovere la parte decimale, lasciando quindi un intero.

Esempio:

db.cats.aggregate(
   [
     {
       $project:
          {
            name: 1,
            randomNumber: { 
              $floor: { 
                $multiply: [ { $rand: {} }, 10 ] 
                } 
              }
          }
     }
   ]
)

Risultato:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 0 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 5 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 7 }

Eccolo di nuovo, ma questa volta lo moltiplichiamo per 100:

db.cats.aggregate(
   [
     {
       $project:
          {
            name: 1,
            randomNumber: { 
              $floor: { 
                $multiply: [ { $rand: {} }, 100 ] 
                } 
              }
          }
     }
   ]
)

Risultato:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 18 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 62 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 92 }

Salva i risultati

Come accennato, $rand genera un nuovo float casuale ogni volta che viene chiamato. Questo va bene se vogliamo un nuovo numero casuale ogni volta che eseguiamo il codice, ma cosa succede se vogliamo memorizzare il numero casuale in ogni documento?

Per memorizzare il numero casuale nel documento, possiamo usare il $addFields operatore (o il suo alias $set ) per aggiungere il nuovo campo al documento.

Esempio:

db.cats.aggregate(
   [
      { $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } },
      { $set: { randomNumber: { $floor: "$randomNumber" } } },
      { $merge: "cats" }
   ]
)

In questo esempio, separiamo l'operazione su due $set fasi e un $merge fase.

Il $merge stage scrive i risultati della pipeline di aggregazione in una raccolta specificata e deve essere l'ultima fase della pipeline.

Ora, quando restituiamo i documenti da quella raccolta (ad esempio utilizzando un metodo come find() ), possiamo vedere che ogni documento contiene il nuovo campo con il numero casuale:

db.cats.find()

Risultato:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }

Ora il numero casuale è persistente. Possiamo restituire i documenti tutte le volte che vogliamo e il numero casuale rimarrà lo stesso.

Eseguiamo find() ancora:

db.cats.find()

Risultato:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }

Esattamente lo stesso numero casuale.