MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Schemat ocen użytkowników — baza danych kluczy/wartości

Przede wszystkim „Słownik w klasie użytkownika” nie jest dobrym pomysłem. Dlaczego? Dodanie obiektu extra rate wymaga przesłania nowego elementu do tablicy, co oznacza, że ​​stary element zostanie usunięty, a to wstawienie jest tak zwane „przenoszenie dokumentu „.

W takim razie, jakie jest właściwe rozwiązanie:załóżmy, że masz kolekcję o nazwie Blogi i chcesz zaimplementować rozwiązanie do oceniania swoich postów na blogu, a dodatkowo śledź każdą operację oceniania opartą na użytkownikach.

Schemat dokumentu bloga wygląda następująco:

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

Potrzebujesz innej kolekcji (stawki) z tym schematem dokumentu:

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

I musisz zdefiniować dla niego odpowiedni indeks:

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

Gdy użytkownik chce ocenić, najpierw musisz sprawdzić, czy użytkownik ocenił post, czy nie. załóżmy, że użytkownik to 'user1' , zapytanie będzie wyglądało następująco

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

I na podstawie ratedBefore , jeśli !ratedBefore następnie wstaw nowy dokument oceny do zbierania cen i zaktualizuj status bloga, w przeciwnym razie użytkownik nie może oceniać

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

Więc co się stanie z rateAverage ?Zdecydowanie polecam obliczenie na podstawie rateCount i rateValue po stronie klienta łatwo jest zaktualizować rateAverage z mongoquery , ale nie powinieneś tego robić. Dlaczego? Prosta odpowiedź brzmi:jest to bardzo łatwe zadanie dla klienta do obsługi tego rodzaju prac i umieszczenie średniej na każdym dokumencie bloga wymaga niepotrzebnej operacji aktualizacji.

średnie zapytanie zostanie obliczone jako:

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

Dzięki takiemu podejściu uzyskasz maksymalną wydajność dzięki mongodb i będziesz mieć możliwość śledzenia każdej stawki w oparciu o użytkownika, post i datę.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. błąd spring-mongo-1.0.xsd

  2. więcej niż jeden indeks 2dsphere, nie jestem pewien, który uruchomić geoNear

  3. Unikalny indeks w mongoDB 3.2 ignorujący wartości null

  4. przekonwertować obiekt mongodb na obiekt javascript

  5. Dlaczego MongoDB jest tak szybki