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 entre0
e1
. 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 }