sql >> Base de Datos >  >> NoSQL >> MongoDB

3 formas de devolver una muestra aleatoria de documentos de una colección de MongoDB

Si necesita devolver una pequeña muestra de documentos aleatorios de una colección, aquí hay tres enfoques que puede probar usando la canalización de agregación.

La $sample Etapa

El $sample La etapa de canalización de agregación está diseñada específicamente para seleccionar aleatoriamente un número específico de documentos.

Cuando usas $sample , especifica la cantidad de documentos que desea devolver en un size campo.

Supongamos que tenemos la siguiente colección llamada 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 }

Podemos usar $sample para tomar una muestra aleatoria de esos documentos como este:

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

Resultado:

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

En este caso, especifiqué { size: 3 } que devolvió tres documentos.

Aquí está nuevamente usando un tamaño de muestra diferente:

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

Resultado:

{ "_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 }

El $sample El escenario funciona de una de dos maneras, dependiendo de cuántos documentos hay en la colección, el tamaño de la muestra en relación con la cantidad de documentos en la colección y su posición en la canalización. Ver MongoDB $sample para obtener una explicación de cómo funciona.

También es posible que el $sample etapa podría devolver el mismo documento más de una vez en su conjunto de resultados.

El $rand Operador

El $rand El operador se introdujo en MongoDB 4.4.2 y su propósito es devolver un flotante aleatorio entre 0 y 1 cada vez que se llama.

Por lo tanto, podemos usarlo en el $match etapa junto con otros operadores, como $expr y $lt para devolver una muestra aleatoria de documentos.

Ejemplo:

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

Resultado:

{ "_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 }

El conjunto de resultados de este enfoque es diferente al $sample enfoque, en el sentido de que no devuelve un número fijo de documentos. El número de documentos devueltos con este enfoque puede variar.

Por ejemplo, esto es lo que sucede cuando ejecuto el mismo código varias veces más.

Conjunto de resultados 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 }

Conjunto de resultados 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 }

Conjunto de resultados 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 }

Conjunto de resultados 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 }

El $sampleRate Operador

Introducido en MongoDB 4.4.2, el $sampleRate operator proporciona una forma más concisa de hacer lo mismo que en el ejemplo anterior.

Cuando usas $sampleRate , proporcione una frecuencia de muestreo como un número de coma flotante entre 0 y 1 . El proceso de selección utiliza una distribución aleatoria uniforme, y la frecuencia de muestreo que proporciona representa la probabilidad de que un documento determinado sea seleccionado a medida que pasa por la canalización.

Ejemplo:

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

Resultado:

{ "_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 }

Y ejecutarlo de nuevo:

{ "_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 }

Y de nuevo:

{ "_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 }