2012-09-30 48 views
6

Tengo una colección mongo con documentos. Hay un campo en cada documento que es 0 O 1. Necesito muestrear aleatoriamente 1000 registros de la base de datos y contar el número de documentos que tienen ese campo como 1. Necesito hacer este muestreo 1000 veces. Cómo lo hago ?Muestreo aleatorio de Mongo

+1

¿Podría aceptar una respuesta? –

+0

posible duplicado de [Registro aleatorio de MongoDB] (http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –

+0

Hola Aditya, ¿puedes aceptar una respuesta? – dalanmiller

Respuesta

1

He aquí un ejemplo en la cáscara mongo .. suponiendo una colección de collname, y un valor de interés en thefield:

var total = db.collname.count(); 
var count = 0; 
var numSamples = 1000; 

for (i = 0; i < numSamples; i++) { 
    var random = Math.floor(Math.random()*total); 
    var doc = db.collname.find().skip(random).limit(1).next(); 
    if (doc.thefield) { 
     count += (doc.thefield == 1); 
    } 
} 
+0

Esto también responde a otra pregunta: que a diferencia de SQL, MongoDB no tiene una función incorporada para esto realmente.También ese omisión podría (... podría) ser problemático para valores aleatorios más grandes, sin embargo depende. – Sammaye

1

que iba a editar mi comentario sobre @Stennies contesto con esto, pero también se podría use un índice de ID de aumento automático seprate aquí como alternativa si omitiera GRANDES cantidades de registro (hablando mucho aquí).

me escribió otra respuesta a otra pregunta mucho como este en el que alguien estaba tratando de encontrar el registro número n de la colección:

php mongodb find nth entry in collection

La segunda parte de mi respuesta describe básicamente un método potencial cuál podría abordar este problema Todavía necesitarías repetir 1000 veces para obtener la fila aleatoria del curso.

12

Para MongoDB 3.0 y anteriores, utilizo un viejo truco de los días de SQL (que creo que Wikipedia usa para su función de página aleatoria). Guardo un número aleatorio entre 0 y 1 en cada objeto que necesito aleatorizar, llamemos a ese campo "r". Luego agrega un índice en "r".

db.coll.ensureIndex(r: 1); 

Ahora para obtener x objetos al azar, que utilice:

var startVal = Math.random(); 
db.coll.find({r: {$gt: startVal}}).sort({r: 1}).limit(x); 

Esto le da objetos al azar en una sola consulta de búsqueda. Dependiendo de sus necesidades, esto puede ser excesivo, pero si va a hacer un montón de muestreo en el tiempo, esta es una forma muy eficiente sin poner carga en su back-end.

+0

¡Genial! ¡Muy inteligente! –

+0

¡solución elegante! –

-1

Si está utilizando mongoengine, puede usar un SequenceField para generar un contador incremental.

class User(db.DynamicDocument): 
    counter = db.SequenceField(collection_name="user.counters") 

A continuación, en busca de una lista aleatoria de, digamos, 100, haga lo siguiente

def get_random_users(number_requested): 
    users_to_fetch = random.sample(range(1, User.objects.count() + 1), min(number_requested, User.objects.count())) 
    return User.objects(counter__in=users_to_fetch) 

donde llamarían

get_random_users(100)