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

3 modi per restituire un campione casuale di documenti da una raccolta MongoDB

Se devi restituire un piccolo campione di documenti casuali da una raccolta, ecco tre approcci che puoi provare utilizzando la pipeline di aggregazione.

Il $sample Fase

Il $sample La fase della pipeline di aggregazione è progettata specificamente per la selezione casuale di un numero specificato di documenti.

Quando usi $sample , specifichi il numero di documenti che desideri restituire in una size campo.

Supponiamo di avere la seguente raccolta chiamata pets :

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }

Possiamo usare $sample per prendere un campione casuale di quei documenti come questo:

db.pets.aggregate(
   [
      { 
        $sample: { size: 3 } 
      }
   ]
)

Risultato:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }

In questo caso ho specificato { size: 3 } che ha restituito tre documenti.

Eccolo di nuovo utilizzando una dimensione del campione diversa:

db.pets.aggregate(
   [
      { 
        $sample: { size: 5 } 
      }
   ]
)

Risultato:

{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }

Il $sample stage funziona in due modi, a seconda di quanti documenti ci sono nella raccolta, della dimensione del campione relativa al numero di documenti nella raccolta e della sua posizione nella pipeline. Vedi MongoDB $sample per una spiegazione di come funziona.

È anche possibile che il $sample stage potrebbe restituire lo stesso documento più di una volta nel suo set di risultati.

Il $rand Operatore

Il $rand operatore è stato introdotto in MongoDB 4.4.2 e il suo scopo è restituire un float casuale compreso tra 0 e 1 ogni volta che viene chiamato.

Pertanto, possiamo usarlo nel $match stage insieme ad altri operatori, come $expr e $lt per restituire un campione casuale di documenti.

Esempio:

db.pets.aggregate(
   [
      { 
        $match: 
          { 
            $expr: 
              { 
                $lt: [ 0.5, { $rand: {} } ] 
              }
          } 
      }
   ]
)

Risultato:

{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }

Il set di risultati di questo approccio è diverso da $sample approccio, in quanto non restituisce un numero fisso di documenti. Il numero di documenti restituiti con questo approccio può variare.

Ad esempio, ecco cosa succede quando eseguo lo stesso codice più volte.

Risultato set 2:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }

Risultato set 3:

{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }

Risultato set 4:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }

Risultato set 5:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }

Il $sampleRate Operatore

Introdotto in MongoDB 4.4.2, il $sampleRate operatore fornisce un modo più conciso per fare lo stesso dell'esempio precedente.

Quando usi $sampleRate , fornisci una frequenza di campionamento come numero in virgola mobile compreso tra 0 e 1 . Il processo di selezione utilizza una distribuzione casuale uniforme e la frequenza di campionamento fornita rappresenta la probabilità che un determinato documento venga selezionato mentre passa attraverso la pipeline.

Esempio:

db.pets.aggregate(
   [
      { 
        $match: { $sampleRate: 0.5 } 
      }
   ]
)

Risultato:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 5, "name" : "Bruce", "type" : "Bat", "weight" : 3 }
{ "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }

Ed eseguilo di nuovo:

{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
{ "_id" : 7, "name" : "Punch", "type" : "Gorilla", "weight" : 300 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }
{ "_id" : 9, "name" : "Flutter", "type" : "Hummingbird", "weight" : 1 }

E ancora:

{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 }
{ "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 }
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
{ "_id" : 8, "name" : "Snap", "type" : "Crocodile", "weight" : 400 }