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

Как да моделираме система за гласуване с харесвания с MongoDB

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

{ 
    "_id": ObjectId("54bb201aa3a0f26f885be2a3")
    "photo": "imagename.png",
    "likeCount": 0
    "likes": []
}

Какъвто и да е случаят, има уникален "_id" за вашата "снимка публикация" и каквато информация искате, но след това другите полета, както е споменато. Свойството "likes" тук е масив и ще съдържа уникалните стойности "_id" от обектите "user" във вашата система. Така че всеки „потребител“ има свой собствен уникален идентификатор някъде, или в локално хранилище, или OpenId или нещо подобно, но уникален идентификатор. Ще се придържам към ObjectId за примера.

Когато някой изпрати „харесване“ на публикация, искате да издадете следното изявление за актуализиране:

db.photos.update(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
        "likes": { "$ne": ObjectId("54bb2244a3a0f26f885be2a4") }
    },
    {
        "$inc": { "likeCount": 1 },
        "$push": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") }
    }
)

Сега $inc операция там ще увеличи стойността на "likeCount" с посоченото число, така че увеличете с 1. $push операцията добавя уникалния идентификатор за потребителя към масива в документа за бъдещи справки.

Основното важно тук е да се води запис на онези потребители, които са гласували и какво се случва в частта „запитване“ на изявлението. Освен избора на документа за актуализиране чрез собствен уникален „_id“, другото важно нещо е да проверите този масив „likes“, за да се уверите, че текущият гласувал потребител вече не е там.

Същото важи и за обратния случай или „премахването“ на „харесването“:

db.photos.update(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
        "likes": ObjectId("54bb2244a3a0f26f885be2a4")
    },
    {
        "$inc": { "likeCount": -1 },
        "$pull": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") }
    }
)

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

Разбира се, не е практично да четете масив с няколкостотин записа в документ обратно във всяка друга част на вашето приложение. Но MongoDB има много стандартен начин да се справи и с това:

db.photos.find(
    { 
        "_id": ObjectId("54bb201aa3a0f26f885be2a3"), 
    },
    { 
       "photo": 1
       "likeCount": 1,
       "likes": { 
          "$elemMatch": { "$eq": ObjectId("54bb2244a3a0f26f885be2a4") }
       }
    }
)

Това използване на $elemMatch в проекция ще върне текущия потребител само ако присъства или просто празен масив, където не е. Това позволява на останалата част от логиката на приложението ви да е наясно дали текущият потребител вече е гласувал или не.

Това е основната техника и може да работи за вас, както е, но трябва да сте наясно, че вградените масиви не трябва да се разширяват безкрайно, а също така има твърдо ограничение от 16MB за BSON документи. Така че концепцията е добра, но просто не може да се използва самостоятелно, ако очаквате 1000 „харесвания“ на вашето съдържание. Има концепция, известна като "bucketing", която се обсъжда в някои подробности в този пример за дизайн на хибридна схема, която позволява на едно решение да съхранява голям обем "харесвания". Можете да го разгледате, за да използвате заедно с основните концепции тук, като начин да направите това на обем.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongodb concat int и низ

  2. Актуализация на колекцията от метеори с традиционен идентификатор

  3. Групирайте записи по месеци и ги пребройте - Mongoose, nodeJs, mongoDb

  4. NodeJS и MongoDB FindAndModify() трябва да бъдат премахнати или актуализирани

  5. Как мога да изтегля поддокументи от масив?