MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

3 maneiras de retornar uma amostra aleatória de documentos de uma coleção do MongoDB


Se você precisar retornar uma pequena amostra de documentos aleatórios de uma coleção, aqui estão três abordagens que você pode tentar usando o pipeline de agregação.

A $sample Estágio


O $sample O estágio de pipeline de agregação é projetado especificamente para selecionar aleatoriamente um número especificado de documentos.

Quando você usa $sample , você especifica o número de documentos que deseja devolver em um size campo.

Suponha que temos a seguinte coleção chamada pets :
{ "_id" :1, "name" :"Wag", "type" :"Dog", "weight" :20 }{ "_id" :2, "name" :"Latido", "tipo" :"Dog", "weight" :10 }{ "_id" :3, "name" :"Miau", "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" :"Canguru", "weight" :130 }{ "_id" :7, "name" :"Punch", "type" :"Gorilla", "weight" :300 }{ "_id" :8, "name" :"Snap", "type" :"Crocodile", "weight" :400 }{ "_id" :9, "name" :"Flutter", "type" :"Beija-flor", "peso" :1 }

Podemos usar $sample para pegar uma amostra aleatória desses documentos como este:
db.pets.aggregate( [ { $amostra:{ tamanho:3 } } ])

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

Nesse caso, especifiquei { size: 3 } que devolveu três documentos.

Aqui está novamente usando um tamanho de amostra diferente:
db.pets.aggregate(
   [
      { 
        $sample: { size: 5 } 
      }
   ]
) 

Resultado:
{ "_id" :6, "name" :"Hop", "type" :"Canguru", "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 } 
O $sample O estágio funciona de duas maneiras, dependendo de quantos documentos estão na coleção, o tamanho da amostra em relação ao número de documentos na coleção e sua posição no pipeline. Veja MongoDB $sample para uma explicação de como funciona.

Também é possível que o $sample stage poderia retornar o mesmo documento mais de uma vez em seu conjunto de resultados.

O $rand Operador


O $rand O operador foi introduzido no MongoDB 4.4.2 e seu objetivo é retornar um float aleatório entre 0 e 1 cada vez que é chamado.

Portanto, podemos usá-lo no $match stage em conjunto com outros operadores, como $expr e $lt para retornar uma amostra aleatória de documentos.

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

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

O conjunto de resultados desta abordagem é diferente do $sample abordagem, na medida em que não retorna um número fixo de documentos. O número de documentos retornados com essa abordagem pode variar.

Por exemplo, aqui está o que acontece quando executo o mesmo código várias vezes.

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" :"Latido", "type" :"Cachorro", "peso" :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" :"Miau", "type" :"Cat", "weight" :7 }{ "_id" :6, "name" :"Hop", "type" :"Canguru", "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 } 

A $sampleRate Operador


Introduzido no MongoDB 4.4.2, o $sampleRate O operador fornece uma maneira mais concisa de fazer o mesmo que o exemplo anterior.

Quando você usa $sampleRate , você fornece uma taxa de amostragem como um número de ponto flutuante entre 0 e 1 . O processo de seleção usa uma distribuição aleatória uniforme e a taxa de amostragem que você fornece representa a probabilidade de um determinado documento ser selecionado ao passar pelo pipeline.

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

Resultado:
{ "_id" :1, "name" :"Wag", "type" :"Dog", "weight" :20 }{ "_id" :2, "name" :"Latido", "tipo" :"Dog", "weight" :10 }{ "_id" :5, "name" :"Bruce", "type" :"Bat", "weight" :3 }{ "_id" :6, "name" :"Hop", "type" :"Canguru", "weight" :130 }{ "_id" :7, "name" :"Punch", "type" :"Gorilla", "weight" :300 }{ " _id" :8, "name" :"Snap", "type" :"Crocodilo", "peso" :400 }

E execute novamente:
{ "_id" :3, "name" :"Miau", "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 de novo:
{ "_id" :1, "name" :"Wag", "type" :"Dog", "weight" :20 }{ "_id" :2, "name" :"Latido", "tipo" :"Cão", "peso" :10 }{ "_id" :3, "nome" :"Miau", "tipo" :"Gato", "peso" :7 }{ "_id" :8, "nome" :"Snap", "type" :"Crocodile", "weight" :400 }