sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB:jak najít 10 náhodných dokumentů ve sbírce 100?

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í)



  1. Jak se připojím k mongodb pomocí node.js (a ověřím)?

  2. Jak nastavit _id na dokument db v Mongoose?

  3. Jak se dotazuji na odkazované objekty v MongoDB?

  4. Obnovte databázi MongoDB pomocí mongorestore