No MongoDB, o
$rand operador de pipeline de agregação retorna um float aleatório entre 0 e 1. O valor de ponto flutuante tem até 17 dígitos após o ponto decimal. Quaisquer zeros à direita são descartados, portanto, o número de dígitos pode variar.
O
$rand O operador foi introduzido no MongoDB 4.4.2. Exemplo
Suponha que tenhamos uma coleção chamada
cats com os seguintes documentos:{ "_id" :1, "name" :"Scratch" }{ "_id" :2, "name" :"Miau" }{ "_id" :3, "name" :"Fofo" }
Podemos usar o $rand operador para gerar um número aleatório para cada gato:
db.cats.aggregate( [ { $project:{ randomNumber:{ $rand:{} } } } ])
Resultado:
{ "_id" :1, "randomNumber" :0.5593964875463812 }{ "_id" :2, "randomNumber" :0.04357301703691149 }{ "_id" :3, "randomNumber" :0.7556877215199272 }
O $rand operador não aceita nenhum argumento – basta chamá-lo usando $rand:{} .
Além disso, $rand gera um novo número cada vez que é chamado. Portanto, executar o código acima várias vezes produzirá um número aleatório diferente para cada gato.
Apenas para demonstrar isso, vou executá-lo novamente e aqui está o novo resultado:
{ "_id" :1, "randomNumber" :0.19672627212049873 }{ "_id" :2, "randomNumber" :0.05513133909795318 }{ "_id" :3, "randomNumber" :0.7509841462815067 }
Podemos ver que os números aleatórios são diferentes dos gerados no exemplo anterior.
Números aleatórios maiores que 1
Como mencionado, $rand retorna um float aleatório entre 0 e 1. Isso é bom se não nos importamos em obter um zero, seguido por até 17 casas decimais aleatórias.
Mas e se quisermos um número aleatório maior que 1?
Nesses casos, podemos usar o $multiply operador para multiplicar o resultado de $rand .
Exemplo:
db.cats.aggregate( [ { $project:{ randomNumber:{ $multiply:[ { $rand:{} }, 10 ] } } } ])
Resultado:
{ "_id" :1, "randomNumber" :1.958938543288535 }{ "_id" :2, "randomNumber" :4.437057321655847 }{ "_id" :3, "randomNumber" :8.238909118372334 } Inteiro aleatório
Também podemos querer acabar com a parte fracionária. Neste caso, podemos usar um operador como $floor para remover a parte decimal, deixando assim um inteiro.
Exemplo:
db.cats.aggregate( [ { $project:{ name:1, randomNumber:{ $floor:{ $multiply:[ { $rand:{} }, 10 ] } } } } ])
Resultado:
{ "_id" :1, "name" :"Scratch", "randomNumber" :0 }{ "_id" :2, "name" :"Meow", "randomNumber" :5 }{ "_id" :3, "name" :"Fofo", "randomNumber" :7 }
Aqui está novamente, mas desta vez multiplicamos por 100:
db.cats.aggregate( [ { $project:{ name:1, randomNumber:{ $floor:{ $multiply:[ { $rand:{} }, 100 ] } } } } ])
Resultado:
{ "_id" :1, "name" :"Scratch", "randomNumber" :18 }{ "_id" :2, "name" :"Meow", "randomNumber" :62 }{ "_id" :3, "name" :"Fofo", "randomNumber" :92 } Salvar os resultados
Como mencionado, $rand gera um novo float aleatório cada vez que é chamado. Isso é bom se quisermos um novo número aleatório toda vez que executarmos o código, mas e se quisermos armazenar o número aleatório em cada documento?
Para armazenar o número aleatório no documento, podemos usar o $addFields operador (ou seu alias $set ) para adicionar o novo campo ao documento.
Exemplo:
db.cats.aggregate( [ { $set:{ randomNumber:{ $multiply:[ { $rand:{} }, 100 ] } } }, { $set:{ randomNumber:{ $floor:"$randomNumber" } } }, { $merge:"cats" } ])
Neste exemplo, separamos a operação em dois $set estágios e um $merge etapa.
O $merge stage grava os resultados do pipeline de agregação em uma coleção especificada e deve ser o último estágio no pipeline.
Agora, quando retornamos os documentos dessa coleção (por exemplo, usando um método como find() ), podemos ver que cada documento contém o novo campo com o número aleatório:
db.cats.find()
Resultado:
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, "name" :"Fofo", "randomNumber" :73 }
Agora o número aleatório é persistente. Podemos devolver os documentos quantas vezes quisermos, e o número aleatório permanecerá o mesmo.
Vamos executar find() novamente:
db.cats.find()
Resultado:
{ "_id" :1, "name" :"Scratch", "randomNumber" :61 }{ "_id" :2, "name" :"Meow", "randomNumber" :86 }{ "_id" :3, "name" :"Fofo", "randomNumber" :73 }
Exatamente o mesmo número aleatório.