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

MongoDB $ rand

En MongoDB, el $rand El operador de canalización de agregación devuelve un flotante aleatorio entre 0 y 1.

El valor de punto flotante tiene hasta 17 dígitos después del punto decimal. Los ceros finales se eliminan, por lo que la cantidad de dígitos puede variar.

El $rand El operador se introdujo en MongoDB 4.4.2.

Ejemplo

Supongamos que tenemos una colección llamada cats con los siguientes documentos:

{ "_id" : 1, "name" : "Scratch" }
{ "_id" : 2, "name" : "Meow" }
{ "_id" : 3, "name" : "Fluffy" }

Podemos usar el $rand operador para generar un número aleatorio 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 }

El $rand El operador no acepta ningún argumento; simplemente lo llama usando $rand: {} .

Además, $rand genera un nuevo número cada vez que se llama. Por lo tanto, ejecutar el código anterior varias veces generará un número aleatorio diferente para cada gato.

Solo para demostrar esto, lo ejecutaré de nuevo y aquí está el nuevo resultado:

{ "_id" : 1, "randomNumber" : 0.19672627212049873 }
{ "_id" : 2, "randomNumber" : 0.05513133909795318 }
{ "_id" : 3, "randomNumber" : 0.7509841462815067 }

Podemos ver que los números aleatorios son diferentes a los generados en el ejemplo anterior.

Números aleatorios mayores que 1

Como se mencionó, $rand devuelve un flotante aleatorio entre 0 y 1. Esto está bien si no nos importa obtener un cero, seguido de hasta 17 decimales aleatorios.

Pero, ¿y si queremos un número aleatorio mayor que 1?

En tales casos, podemos usar el $multiply operador para multiplicar el resultado de $rand .

Ejemplo:

db.cats.aggregate(
   [
     {
       $project:
          {
            randomNumber: { $multiply: [ { $rand: {} }, 10 ] }
          }
     }
   ]
)

Resultado:

{ "_id" : 1, "randomNumber" : 1.958938543288535 }
{ "_id" : 2, "randomNumber" : 4.437057321655847 }
{ "_id" : 3, "randomNumber" : 8.238909118372334 }

Entero aleatorio

También podríamos querer eliminar la parte fraccionaria. En este caso, podemos usar un operador como $floor para eliminar la parte decimal, dejando así un número entero.

Ejemplo:

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" : "Fluffy", "randomNumber" : 7 }

Aquí está de nuevo, pero esta vez lo 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" : "Fluffy", "randomNumber" : 92 }

Guardar los resultados

Como se mencionó, $rand genera un nuevo flotante aleatorio cada vez que se llama. Esto está bien si queremos un nuevo número aleatorio cada vez que ejecutamos el código, pero ¿qué sucede si queremos almacenar el número aleatorio en cada documento?

Para almacenar el número aleatorio en el documento, podemos usar $addFields operador (o su alias $set ) para agregar el nuevo campo al documento.

Ejemplo:

db.cats.aggregate(
   [
      { $set: { randomNumber: { $multiply: [ { $rand: {} }, 100 ] } } },
      { $set: { randomNumber: { $floor: "$randomNumber" } } },
      { $merge: "cats" }
   ]
)

En este ejemplo, separamos la operación en dos $set etapas y un $merge escenario.

El $merge etapa escribe los resultados de la tubería de agregación en una colección específica, y debe ser la última etapa de la tubería.

Ahora, cuando devolvemos los documentos de esa colección (por ejemplo, usando un método como find() ), podemos ver que cada documento contiene el nuevo campo con el número aleatorio:

db.cats.find()

Resultado:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }

Ahora el número aleatorio es persistente. Podemos devolver los documentos tantas veces como queramos y el número aleatorio seguirá siendo el mismo.

Ejecutemos find() de nuevo:

db.cats.find()

Resultado:

{ "_id" : 1, "name" : "Scratch", "randomNumber" : 61 }
{ "_id" : 2, "name" : "Meow", "randomNumber" : 86 }
{ "_id" : 3, "name" : "Fluffy", "randomNumber" : 73 }

Exactamente el mismo número aleatorio.