MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB:как да намерите 10 произволни документа в колекция от 100?

На това беше отговорено много отдавна и оттогава MongoDB значително се е развил.

Както е публикувано в друг отговор, MongoDB вече поддържа вземане на проби в рамките на Aggregation Framework от версия 3.2:

Начинът, по който можете да направите това е:

db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs

Или:

db.products.aggregate([
  {$match: {category:"Electronic Devices"}}, // filter the results
  {$sample: {size: 5}} // You want to get 5 docs
]);

Има обаче някои предупреждения относно оператора $sample:

(от 6 ноември 2017 г., където последната версия е 3.4) => Ако нещо от това не е изпълнено:

  • $sample е първият етап от конвейера
  • N е по-малко от 5% от общия брой документи в колекцията
  • Колекцията съдържа повече от 100 документа

Ако някое от горните условия НЕ е изпълнено, $sample извършва сканиране на колекция, последвано от произволно сортиране, за да избере N документа.

Както в последния пример с $match

СТАР ОТГОВОР

Винаги можете да стартирате:

db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)

Но редът няма да е произволен и ще ви трябват две заявки (едно броене, за да получите YOUR_COLLECTION_SIZE) или преценете колко голям е (това е около 100 записа, около 1000, около 10000...)

Можете също да добавите поле към всички документи с произволен номер и да направите заявка по този номер. Недостатъкът тук би бил, че ще получавате същите резултати всеки път, когато изпълнявате една и съща заявка. За да коригирате това, винаги можете да играете с лимит и пропускане или дори със сортиране. бихте могли също да актуализирате тези произволни числа всеки път, когато извличате запис (предполага повече заявки).

--Не знам дали използвате Mongoose, Mondoid или директно Mongo Driver за конкретен език, така че ще напиша всичко за mongo shell.

Така вашият, да кажем, продуктов запис ще изглежда така:

{
 _id: ObjectId("..."),
 name: "Awesome Product",
 category: "Electronic Devices",
}

и бих предложил да използвате:

{
 _id: ObjectId("..."),
 name: "Awesome Product",
 category: "Electronic Devices",
 _random_sample: Math.random()
}

Тогава можете да направите:

db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})

след това можете да изпълнявате периодично, така че периодично да актуализирате полето _random_sample на документа:

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)

или просто всеки път, когато извлечете някои записи, можете да актуализирате всички или само няколко (в зависимост от това колко записа сте изтеглили)

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);
}

РЕДАКТИРАНЕ

Имайте предвид, че

db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)

няма да работи много добре, тъй като ще актуализира всички продукти, които отговарят на вашата заявка, с същите произволно число. Последният подход работи по-добре (актуализиране на някои документи, докато ги извличате)



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Не мога да използвам командата mongo, показва командата, която не е намерена на mac

  2. Node + Mongoose:Получаване на последно въведен ID?

  3. Преглед на оперативното отчитане на базата данни в ClusterControl

  4. Кой е най-добрият начин за съхраняване на дати в MongoDB?

  5. elasticsearch v.s. MongoDB за приложение за филтриране