¿Cómo puedo obtener un registro aleatorio de MongoDB?

Resuelto Will M asked hace 14 años • 0 respuestas

Estoy buscando obtener un registro aleatorio de una colección enorme (100 millones de registros).

¿Cuál es la forma más rápida y eficiente de hacerlo?

Los datos ya están ahí y no hay ningún campo en el que pueda generar un número aleatorio y obtener una fila aleatoria.

Will M avatar May 13 '10 09:05 Will M
Aceptado

A partir de la versión 3.2 de MongoDB, puede obtener N documentos aleatorios de una colección utilizando el $sampleoperador de canalización de agregación:

// Get one random document from the mycoll collection.
db.mycoll.aggregate([{ $sample: { size: 1 } }])

Si desea seleccionar los documentos aleatorios de un subconjunto filtrado de la colección, anteponga una $matchetapa a la canalización:

// Get one random document matching {a: 10} from the mycoll collection.
db.mycoll.aggregate([
    { $match: { a: 10 } },
    { $sample: { size: 1 } }
])

Como se indica en los comentarios, cuando sizees mayor que 1, puede haber duplicados en la muestra del documento devuelto.

JohnnyHK avatar Nov 07 '2015 02:11 JohnnyHK

Haga un recuento de todos los registros, genere un número aleatorio entre 0 y el recuento y luego haga:

db.yourCollection.find().limit(-1).skip(yourRandomNumber).next()
ceejayoz avatar May 13 '2010 02:05 ceejayoz

Actualización para MongoDB 3.2

3.2 introdujo $sample en el canal de agregación.

También hay una buena publicación de blog sobre cómo ponerlo en práctica.

Para versiones anteriores (respuesta anterior)

En realidad, se trataba de una solicitud de función: http://jira.mongodb.org/browse/SERVER-533 , pero se archivó en "No se solucionará".

El libro de cocina tiene una muy buena receta para seleccionar un documento aleatorio de una colección: http://cookbook.mongodb.org/patterns/random-attribute/

Parafraseando la receta, asigna números aleatorios a sus documentos:

db.docs.save( { key : 1, ..., random : Math.random() } )

Luego seleccione un documento aleatorio:

rand = Math.random()
result = db.docs.findOne( { key : 2, random : { $gte : rand } } )
if ( result == null ) {
  result = db.docs.findOne( { key : 2, random : { $lte : rand } } )
}

Consultando con ambos $gtees $ltenecesario encontrar el documento con un número aleatorio más cercano rand.

Y, por supuesto, querrás indexar en el campo aleatorio:

db.docs.ensureIndex( { key : 1, random :1 } )

Si ya está consultando un índice, simplemente suéltelo, agréguelo random: 1y agréguelo nuevamente.

Michael avatar Apr 01 '2011 18:04 Michael

También puede utilizar la función de indexación geoespacial de MongoDB para seleccionar los documentos "más cercanos" a un número aleatorio.

Primero, habilite la indexación geoespacial en una colección:

db.docs.ensureIndex( { random_point: '2d' } )

Para crear un conjunto de documentos con puntos aleatorios en el eje X:

for ( i = 0; i < 10; ++i ) {
    db.docs.insert( { key: i, random_point: [Math.random(), 0] } );
}

Luego puedes obtener un documento aleatorio de la colección como este:

db.docs.findOne( { random_point : { $near : [Math.random(), 0] } } )

O puedes recuperar varios documentos más cercanos a un punto aleatorio:

db.docs.find( { random_point : { $near : [Math.random(), 0] } } ).limit( 4 )

Esto requiere solo una consulta y no verificaciones nulas, además el código es limpio, simple y flexible. Incluso podrías usar el eje Y del geopunto para agregar una segunda dimensión de aleatoriedad a tu consulta.

Nico de Poel avatar Feb 29 '2012 12:02 Nico de Poel