MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Insérer s'il n'existe pas, sinon supprimer MongoDB

Ce n'est pas une bonne façon de mettre en œuvre les votes positifs et négatifs. Outre le fait que le cadre d'agrégation n'est en aucun cas un mécanisme de mise à jour des documents, vous semblez avoir pensé que cela pourrait être une solution en raison de la logique que vous souhaitez mettre en œuvre. Mais l'agrégat ne se met pas à jour.

Ce que vous voulez sur votre, eh bien appelons ça un schéma de "question", c'est une structure comme celle-ci :

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

C'est quelque chose qui peut bien fonctionner avec les mises à jour atomiques et vous donner en même temps des informations avec état sur l'objet.

Pour les tableaux "upvoted" et "downvoted", nous allons considérer que les votes "users" ont une valeur ObjectId unique similaire. Donc, ce que nous allons faire, c'est $push ou $pull à partir de l'un ou l'autre des tableaux et également "incrémenter/décrémenter" les valeurs du compteur avec chacune de ces opérations.

Voici comment cela fonctionne pour un vote positif :

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

En fait, il s'agit de deux opérations, que vous pouvez effectuer avec le AP d'opérations en masse Moi aussi (probablement la meilleure façon vraiment) mais ça a un sens. La première déclaration ne correspondra qu'à un document où l'utilisateur actuel a un "vote négatif" enregistré dans le tableau. En tant que tel, nous avons déjà "poussé" cette valeur d'identifiant d'utilisateur dans le tableau "downvotes". Si ce n'est pas le cas, aucune mise à jour n'est effectuée. Mais vous poussez et tirez à la fois des tableaux respectifs et "incrémentez/décrémentez" les champs de compteur en même temps.

Avec la deuxième déclaration qui ne correspondra qu'à quelque chose où la première ne correspondait pas, vous faites une évaluation juste que maintenant vous n'avez pas besoin de toucher aux "votes négatifs" et gérez simplement les champs de vote positif. Dans les deux cas, la chose la plus sûre à faire est de s'assurer que la condition principale est que la valeur actuelle de l'ID utilisateur n'est pas présente dans le tableau "upvoted".

Pour les votes négatifs, les champs sont simplement inversés :

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

Naturellement, vous pouvez voir la progression logique vers l'annulation simple de tout "vote positif/négatif" pour l'utilisateur en question. Vous pouvez également être intelligent à ce sujet si vous le souhaitez et exposer les informations dans votre client pour non seulement montrer si l'utilisateur actuel a déjà "voté pour/contre", mais aussi contrôler les actions de clic et éliminer les demandes inutiles.