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

Вмъкнете, ако не съществува, в противен случай премахнете MongoDB

Това не е добър начин за прилагане на гласове „за“ и „против“. Освен рамката за агрегиране, която не е механизъм за актуализиране на документи по какъвто и да е начин, изглежда сте гравитирали към мисълта, че това може да е решение поради логиката, която искате да приложите. Но агрегатът не се актуализира.

Това, което искате от вашата схема, нека я наречем "въпрос", е структура като тази:

{
    "_id": ObjectId("53f51a844ffa9b02cf01c074"),
    "upvoted": [],
    "downvoted": [],
    "upvoteCount": 0,
    "downvoteCount": 0
}

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

За масивите с гласуване „за“ и „против“ ще вземем предвид, че гласуването на „потребителите“ има подобна уникална стойност на ObjectId. Така че това, което ще направим, е $push или $pull от двата масива и също така "увеличава/намалява" стойностите на брояча заедно с всяка от тези операции.

Ето как работи това за гласуване за:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1, "downvoteCount": -1 },
        "$pull": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1 },
    }
)

Всъщност това са две операции, които можете да направите с AP за групови операции Аз също (вероятно най-добрият начин наистина), но има смисъл. Първият израз ще съвпадне само с документ, в който текущият потребител има „глас против“, записан в масива. Тъй като вече сме „избутали“ тази стойност на потребителския идентификатор в масива „против гласове“. Ако не е там, тогава не се прави актуализация. Но вие едновременно натискате и изтегляте от съответните масиви и също така едновременно "увеличавате/намалявате" полетата на брояча.

С второто изявление, което ще съвпадне само с нещо, където първото не е, вие правите справедлива преценка, че сега не е нужно да докосвате „против“ и просто да боравите с полетата за гласуване. И в двата случая безопасното нещо, което трябва да направите, е да се уверите, че основното условие е, че текущата стойност на потребителския идентификатор не присъства в масива „upvoted“.

За гласове против полетата просто се обръщат:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$pull": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": -1, "downvoteCount": 1 },
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "downvoteCount": 1 },
    }
)

Естествено можете да видите логичната прогресия към просто отмяна на всяко „гласуване за/против“ за въпросния потребител. Освен това можете да бъдете умни по отношение на това, ако искате, и да разкриете информацията във вашия клиент, за да не само показват дали текущият потребител вече е „гласувал за/против“, но и да контролира действията при кликване и да елиминира ненужните заявки.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Актуализирайте много, ако съществува, в противен случай създайте нов документ за всеки LeadId, който не съществува

  2. Как да използвам агрегирането на MongoDB за пагинация?

  3. Играйте! 2 Framework - Добавяне на Java Mongo драйвер

  4. Разработете схема на база данни за Notify like facebook

  5. Не може да се създаде индекс в Azure DocumentDb с протокол Mongodb