2012-09-30 5 views
6

Ich habe eine Mongo-Sammlung mit Dokumenten. Es gibt ein Feld in jedem Dokument, das 0 ODER 1 ist. Ich muss 1000 Datensätze aus der Datenbank zufällig abfragen und die Anzahl der Dokumente zählen, die dieses Feld als 1 haben. Ich muss diese Abtastung 1000 mal machen. Wie mache ich es ?Random Sampling von Mongo

+1

Könnten Sie bitte eine Antwort akzeptieren? –

+0

mögliches Duplikat von [Zufallsdatensatz von MongoDB] (http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –

+0

Hey Aditya, können Sie bitte eine Antwort akzeptieren? – dalanmiller

Antwort

1

Hier ist ein Beispiel in der mongo Schale .. eine Sammlung von collname, und einen Wert von Interesse in thefield Annahme:

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

Das beantwortet auch eine andere Frage: Im Gegensatz zu SQL hat MongoDB keine eingebaute Funktion dafür.Auch das überspringen kann (... könnte) für größere zufällige Werte problematisch werden, hängt aber davon ab. – Sammaye

1

Ich wird bearbeiten mein Kommentar auf @Stennies mit dieser Antwort, aber man kann auch Verwenden Sie einen separaten Autoinkrementierungs-ID-Index hier als Alternative, wenn Sie über riesige Mengen von Datensatz überspringen (sprechen hier riesig).

Ich schrieb eine andere Antwort auf eine andere Frage viel wie dieser, wo einige eine n-te Datensatz der Sammlung zu finden versuchte:

php mongodb find nth entry in collection

Die zweite Hälfte meiner Antwort beschreibt im Grunde ein mögliches Verfahren durch womit Sie dieses Problem angehen könnten. Sie müssten immer noch 1000 Mal durchlaufen, um die zufällige Reihe zu erhalten.

12

Für MongoDB 3.0 und früher verwende ich einen alten Trick von SQL-Tagen (die ich denke Wikipedia für ihre zufällige Seite Funktion verwenden). Ich speichere eine Zufallszahl zwischen 0 und 1 in jedem Objekt, das ich zufällig zuführen soll, nennen wir dieses Feld "r". Sie fügen dann einen Index für "r" hinzu.

db.coll.ensureIndex(r: 1); 

Jetzt zufällig x Objekte zu erhalten, die Sie verwenden:

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

Dies gibt Ihnen zufällige Objekte in einer einzigen Abfrage finden. Je nach Bedarf kann dies zu viel Aufwand sein, aber wenn Sie im Laufe der Zeit viele Samples durchführen, ist dies eine sehr effiziente Methode, ohne Ihr Backend zu belasten.

+0

Großartig! Sehr schlau! –

+0

elegante Lösung! –

-1

Wenn Sie mongoengine verwenden, können Sie ein SequenceField verwenden, um einen inkrementellen Zähler zu generieren.

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

Dann eine zufällige Liste von sagen wir 100, gehen Sie wie folgt

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) 

wo Sie

get_random_users(100)