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
Antwort
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);
}
}
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
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.
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.
Großartig! Sehr schlau! –
elegante Lösung! –
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)
Für Menschen auf die Antwort kommen, sollten Sie jetzt verwenden das nennen würde holen neue $sample
Aggregationsfunktion, neu in 3.2.
https://docs.mongodb.org/manual/reference/operator/aggregation/sample/
db.collection_of_things.aggregate(
[ { $sample: { size: 15 } } ]
)
Dann einen weiteren Schritt fügen Sie die 0
s zu zählen und 1
s $group
mit der Zählung zu erhalten. Here is an example from the MongoDB docs.
Könnten Sie bitte eine Antwort akzeptieren? –
mögliches Duplikat von [Zufallsdatensatz von MongoDB] (http://stackoverflow.com/questions/2824157/random-record-from-mongodb) –
Hey Aditya, können Sie bitte eine Antwort akzeptieren? – dalanmiller