Ini sudah lama dijawab dan, sejak itu, MongoDB telah berkembang pesat.
Seperti yang diposting di jawaban lain, MongoDB sekarang mendukung pengambilan sampel dalam Kerangka Agregasi sejak versi 3.2:
Cara yang bisa Anda lakukan adalah:
db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
Atau:
db.products.aggregate([
{$match: {category:"Electronic Devices"}}, // filter the results
{$sample: {size: 5}} // You want to get 5 docs
]);
Namun, ada beberapa peringatan tentang operator $sample:
(per 6 November 2017, di mana versi terbaru adalah 3.4) => Jika salah satu dari ini tidak terpenuhi:
- $sample adalah tahap pertama dari pipeline
- N kurang dari 5% dari total dokumen dalam koleksi
- Koleksinya berisi lebih dari 100 dokumen
Jika salah satu kondisi di atas TIDAK terpenuhi, $sample melakukan pemindaian koleksi diikuti dengan pengurutan acak untuk memilih N dokumen.
Seperti pada contoh terakhir dengan $match
JAWABAN LAMA
Anda selalu dapat menjalankan:
db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
Tetapi urutannya tidak akan acak dan Anda akan memerlukan dua kueri (satu hitungan untuk mendapatkan YOUR_COLLECTION_SIZE) atau perkirakan seberapa besar (sekitar 100 record, sekitar 1000, sekitar 10.000...)
Anda juga bisa menambahkan bidang ke semua dokumen dengan nomor acak dan kueri dengan nomor itu. Kekurangannya di sini adalah Anda akan mendapatkan hasil yang sama setiap kali Anda menjalankan kueri yang sama. Untuk mengatasinya, Anda selalu dapat bermain dengan batas dan lewati atau bahkan dengan pengurutan. Anda juga dapat memperbarui nomor acak tersebut setiap kali Anda mengambil catatan (menyiratkan lebih banyak kueri).
--Saya tidak tahu apakah Anda menggunakan Mongoose, Mondoid atau langsung Driver Mongo untuk bahasa tertentu, jadi saya akan menulis semua tentang shell mongo.
Jadi, katakanlah, catatan produk Anda akan terlihat seperti ini:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
}
dan saya akan menyarankan untuk menggunakan:
{
_id: ObjectId("..."),
name: "Awesome Product",
category: "Electronic Devices",
_random_sample: Math.random()
}
Maka Anda dapat melakukan:
db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
kemudian, Anda dapat menjalankannya secara berkala sehingga Anda memperbarui bidang _random_sample dokumen secara berkala:
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)
atau kapan saja Anda mengambil beberapa catatan, Anda dapat memperbarui semuanya atau hanya beberapa (tergantung pada berapa banyak catatan yang telah Anda ambil)
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);
}
EDIT
Ketahuilah bahwa
db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
tidak akan berfungsi dengan baik karena akan memperbarui setiap produk yang cocok dengan kueri Anda dengan sama angka acak. Pendekatan terakhir bekerja lebih baik (memperbarui beberapa dokumen saat Anda mengambilnya)