Dies wurde vor langer Zeit beantwortet und seitdem hat sich MongoDB stark weiterentwickelt.
Wie in einer anderen Antwort gepostet, unterstützt MongoDB jetzt Sampling innerhalb des Aggregation Framework seit Version 3.2:
Sie könnten dies folgendermaßen tun:
db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
Oder:
db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);
Es gibt jedoch einige Warnungen zum $sample-Operator:
(Stand 6. November 2017, wobei die neueste Version 3.4 ist) => Wenn einer dieser Punkte nicht erfüllt ist:
- $sample ist die erste Stufe der Pipeline
- N ist weniger als 5 % der gesamten Dokumente in der Sammlung
- Die Sammlung enthält mehr als 100 Dokumente
Wenn eine der oben genannten Bedingungen NICHT erfüllt ist, führt $sample einen Sammlungsscan durch, gefolgt von einer zufälligen Sortierung, um N Dokumente auszuwählen.
Wie im letzten Beispiel mit dem $match
ALTE ANTWORT
Sie könnten immer Folgendes ausführen:
db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
Aber die Reihenfolge ist nicht zufällig und Sie benötigen zwei Abfragen (eine Zählung, um YOUR_COLLECTION_SIZE zu erhalten) oder schätzen, wie groß sie ist (es sind ungefähr 100 Datensätze, ungefähr 1000, ungefähr 10000 ...)
Sie können auch allen Dokumenten ein Feld mit einer Zufallszahl hinzufügen und nach dieser Zahl abfragen. Der Nachteil hier wäre, dass Sie jedes Mal die gleichen Ergebnisse erhalten, wenn Sie dieselbe Abfrage ausführen. Um das zu beheben, können Sie immer mit Limit und Skip oder sogar mit Sort spielen. Sie könnten diese Zufallszahlen auch jedes Mal aktualisieren, wenn Sie einen Datensatz abrufen (impliziert mehr Abfragen).
--Ich weiß nicht, ob Sie Mongoose, Mondoid oder direkt den Mongo-Treiber für eine bestimmte Sprache verwenden, also werde ich alles über die Mongo-Shell schreiben.
So würde Ihr, sagen wir mal, Produktdatensatz so aussehen:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}
und ich würde vorschlagen zu verwenden:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}
Dann könnten Sie Folgendes tun:
db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
dann könnten Sie es regelmäßig ausführen, um das Feld _random_sample des Dokuments regelmäßig zu aktualisieren:
var your_query = {} //it would impact in your performance if there are a lot of records
your_query = {category: "Electronic Devices"} //Update
//upsert = false, multi = true
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
oder wenn Sie nur einige Datensätze abrufen, können Sie alle oder nur einige aktualisieren (je nachdem, wie viele Datensätze Sie abgerufen haben)
for(var i = 0; i < records.length; i++){
var query = {_id: records[i]._id};
//upsert = false, multi = false
db.products.update(query,{$set:{_random_sample::Math.random()}},false,false);
}
BEARBEITEN
Beachten Sie, dass
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
wird nicht sehr gut funktionieren, da es alle Produkte, die Ihrer Anfrage entsprechen, mit demselben aktualisiert Zufallszahl. Der letzte Ansatz funktioniert besser (Aktualisierung einiger Dokumente, während Sie sie abrufen)