Toto bylo zodpovězeno již dávno a od té doby se MongoDB značně vyvinul.
Jak je uvedeno v jiné odpovědi, MongoDB nyní podporuje vzorkování v rámci agregačního rámce od verze 3.2:
Způsob, jak to můžete udělat, je:
db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
Nebo:
db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);
Existuje však několik varování ohledně operátoru $sample:
(stav k 6. listopadu 2017, kde nejnovější verze je 3.4) => Pokud něco z toho není splněno:
- $sample je první fází procesu
- N je méně než 5 % z celkového počtu dokumentů ve sbírce
- Sbírka obsahuje více než 100 dokumentů
Pokud NENÍ splněna některá z výše uvedených podmínek, $sample provede sběrné skenování následované náhodným řazením pro výběr N dokumentů.
Jako v posledním příkladu s $match
STARÁ ODPOVĚĎ
Vždy můžete spustit:
db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
Pořadí ale nebude náhodné a budete potřebovat dva dotazy (jeden počítejte, abyste získali YOUR_COLLECTION_SIZE) nebo odhadnout, jak je velká (je to asi 100 záznamů, asi 1000, asi 10000...)
Můžete také přidat pole do všech dokumentů s náhodným číslem a dotazovat se podle tohoto čísla. Nevýhodou by zde bylo, že při každém spuštění stejného dotazu získáte stejné výsledky. Chcete-li to opravit, můžete vždy hrát s limitem a přeskakováním nebo dokonce s řazením. můžete také aktualizovat tato náhodná čísla pokaždé, když načtete záznam (vyžaduje více dotazů).
--Nevím, jestli používáte Mongoose, Mondoid nebo přímo Mongo Driver pro nějaký konkrétní jazyk, takže napíšu vše o mongo shellu.
Váš, řekněme, záznam o produktu by tedy vypadal takto:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}
a doporučil bych použít:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}
Pak můžete udělat:
db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
pak byste mohli spouštět pravidelně, abyste pravidelně aktualizovali pole _random_sample dokumentu:
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)
nebo prostě kdykoli načtete nějaké záznamy, můžete je aktualizovat všechny nebo jen několik (v závislosti na tom, kolik záznamů jste získali)
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);
}
UPRAVIT
Uvědomte si, že
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
nebude fungovat dobře, protože aktualizuje všechny produkty, které odpovídají vašemu dotazu, stejným náhodné číslo. Poslední přístup funguje lépe (aktualizace některých dokumentů při jejich načítání)