2012-09-30 10 views
6

Ho una collezione mongo con documenti. C'è un campo in ogni documento che è 0 O 1. Ho bisogno di campionare casualmente 1000 record dal database e contare il numero di documenti che hanno quel campo come 1. Ho bisogno di fare questo campionamento 1000 volte. Come lo faccio ?Campionamento casuale da Mongo

+1

Potresti accettare una risposta? –

+0

possibile duplicato di [Record casuale da MongoDB] (http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –

+0

Hey Aditya, puoi accettare una risposta? – dalanmiller

risposta

1

Ecco un esempio nel mongo shell .. ipotizzando una raccolta di collname, e un valore di interesse 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

Questo risponde anche a un'altra domanda: che a differenza di SQL, MongoDB non ha una funzione incorporata per questo realmente.Anche questo salto potrebbe (... potrebbe) diventare fastidioso per valori casuali più grandi, dipende però. – Sammaye

1

stavo andando modificare il mio commento su @Stennies rispondo con questo, ma si potrebbe anche utilizzare un indice ID incrementale automatico seprate qui come alternativa se si dovessero saltare enormi quantità di record (parlando enorme qui).

ho scritto un'altra risposta ad un'altra domanda molto come questo in cui qualcuno stava cercando di trovare ennesimo record della collezione:

php mongodb find nth entry in collection

La seconda metà della mia risposta fondamentalmente descrive un metodo potenziale che potresti affrontare questo problema. Dovresti comunque ripetere il ciclo 1000 volte per ottenere la riga casuale, naturalmente.

12

Per MongoDB 3.0 e versioni precedenti, utilizzo un vecchio trucco dei giorni SQL (che credo utilizzi Wikipedia per la loro funzione di pagina casuale). Memorizzo un numero casuale compreso tra 0 e 1 in ogni oggetto che ho bisogno di randomizzare, chiamiamolo quel campo "r". Quindi aggiungi un indice su "r".

db.coll.ensureIndex(r: 1); 

Ora per ottenere oggetti x casuali, si utilizza:

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

Questo vi dà oggetti casuali in una singola query di ricerca. A seconda delle tue esigenze, questo potrebbe essere eccessivo, ma se stai andando a fare molti campionamenti nel tempo, questo è un modo molto efficiente senza caricare il tuo back-end.

+0

Ottimo! Molto intelligente! –

+0

soluzione elegante! –

-1

Se si utilizza il mongoengine, è possibile utilizzare un campo Sequence per generare un contatore incrementale.

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

Poi per andare a prendere un elenco casuale di dire al 100, effettuare le seguenti operazioni

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) 

dove si sarebbe chiamata

get_random_users(100)