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

MongoDB $rand


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.