sql >> Database >  >> NoSQL >> MongoDB

MongoDB:hoe vind je 10 willekeurige documenten in een verzameling van 100?

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)



  1. Mongodb telt alle array-elementen in alle objecten die overeenkomen met criteria

  2. Hoe Redis-oproepen in Lua-scriptbeperkingen vermijden?

  3. mongodb tekst zoeken met meerdere velden

  4. Inhoudswaarde zoeken in redis door BookSleeve