Dit is lang geleden beantwoord en sindsdien is MongoDB enorm geëvolueerd.
Zoals gepost in een ander antwoord, ondersteunt MongoDB nu steekproeven binnen het Aggregation Framework sinds versie 3.2:
De manier waarop u dit zou kunnen doen is:
db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
Of:
db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);
Er zijn echter enkele waarschuwingen over de operator $sample:
(vanaf 6 november 2017, waar de laatste versie 3.4 is) => Als aan een van deze punten niet wordt voldaan:
- $sample is de eerste fase van de pijplijn
- N is minder dan 5% van het totale aantal documenten in de collectie
- De collectie bevat meer dan 100 documenten
Als aan een van de bovenstaande voorwaarden NIET wordt voldaan, voert $sample een collectiescan uit, gevolgd door een willekeurige sortering om N documenten te selecteren.
Zoals in het laatste voorbeeld met de $match
OUD ANTWOORD
Je zou altijd kunnen rennen:
db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
Maar de volgorde is niet willekeurig en je hebt twee zoekopdrachten nodig (één telling om YOUR_COLLECTION_SIZE te krijgen) of schat hoe groot het is (het zijn ongeveer 100 records, ongeveer 1000, ongeveer 10000...)
U kunt ook een veld aan alle documenten toevoegen met een willekeurig nummer en op dat nummer zoeken. Het nadeel hiervan zou zijn dat u elke keer dat u dezelfde query uitvoert dezelfde resultaten krijgt. Om dat op te lossen, kun je altijd spelen met limiet en overslaan of zelfs met sorteren. je kunt net zo goed die willekeurige getallen bijwerken elke keer dat je een record ophaalt (wat meer zoekopdrachten inhoudt).
--Ik weet niet of je Mongoose, Mondoid of rechtstreeks de Mongo Driver voor een specifieke taal gebruikt, dus ik zal alles over Mongo Shell schrijven.
Dus uw, laten we zeggen, productrecord ziet er als volgt uit:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}
en ik zou willen voorstellen om te gebruiken:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}
Dan zou je kunnen doen:
db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
dan zou u periodiek kunnen uitvoeren, zodat u het _random_sample-veld van het document periodiek bijwerkt:
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)
of gewoon wanneer u enkele records ophaalt, kunt u ze allemaal bijwerken of slechts een paar (afhankelijk van hoeveel records u hebt opgehaald)
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);
}
BEWERKEN
Houd er rekening mee dat
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
zal niet erg goed werken omdat het alle producten die overeenkomen met uw zoekopdracht met dezelfde . updatet willekeurig nummer. De laatste aanpak werkt beter (sommige documenten bijwerken terwijl u ze ophaalt)