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

Схема за потребителски оценки - База данни за ключ/стойност

Първо, „Речник в потребителски клас“ не е добра идея. защо? Добавянето на обект с допълнителен курс изисква натискане на нов елемент към масива, което означава, че старият елемент ще бъде премахнат, и това вмъкване е така нареченото „преместване на документ ". Преместването на документи е бавно и MongoDB не е толкова добър в повторното използване на празно пространство, така че преместването на много документи може да доведе до големи участъци празен файл с данни (някои текстове в книгата „MongoDB The Definitive Guide").

Тогава кое е правилното решение:приемете, че имате колекция, наречена Блогове, и искате да приложите решение за рейтинг за публикациите в блога си и освен това да следите всяка операция на потребителски процент.

Схемата за блог документ ще бъде като:

{
   _id : ....,
   title: ....,
   ....
   rateCount : 0,
   rateValue : 0,
   rateAverage: 0
}

Имате нужда от друга колекция (тарифи) с тази схема на документа:

{
    _id: ....,
    userId: ....,
    postId:....,
    value: ..., //1 to 5
    date:....   
}

И трябва да дефинирате подходящ индекс за него:

db.Rates.ensureIndex({userId : 1, postId : 1})// very useful. it will result in a much faster search operation in case you want to check if a user has rated the post previously

Когато потребител иска да оцени, първо трябва да проверите дали потребителят е оценил публикацията или не. приемем, че потребителят е 'user1' , тогава заявката ще бъде

var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()

И въз основа на ratedBefore , ако !ratedBefore след това вмъкнете нов документ за оценка в колекцията на тарифите и актуализирайте състоянието на блога, в противен случай потребителят няма право да оценява

if(!ratedBefore)
{
    var postId = 'post1'; // this id sould be passed before by client driver
    var userId = 'user1'; // this id sould be passed before by client driver
    var rateValue = 1; // to 5
    var rate = 
    {       
       userId: userId,
       postId: postId,
       value: rateValue,
       date:new Date()  
    };

    db.Rates.insert(rate);
    db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
}

Тогава какво ще се случи с rateAverage ?Силно препоръчвам да го изчислите въз основа на rateCount и rateValue от страна на клиента е лесно да се актуализира rateAverage с mongoquery , но не трябва да го правите. защо? Простият отговор е:това е много лесна задача за клиента да се справи с този вид работа и поставянето на средна стойност във всеки блог документ изисква ненужна операция за актуализиране.

средната заявка ще бъде изчислена като:

var blog = db.Blog.findOne({"_id" : "post1"});
var avg = blog.rateValue / blog.rateCount;
print(avg);

С този подход ще получите максимална производителност с mongodb и ще следите всяка ставка въз основа на потребител, публикация и дата.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. GroupBy множество колони в MongoDB

  2. Redis срещу MongoDB:Какво трябва да знаете

  3. Mongodb repica задава конфигурация във файл със свойства

  4. SQL RPAD()

  5. Mongo $addToSet с множество стойности правилен синтаксис