sql >> Database teknologi >  >> NoSQL >> MongoDB

Indsæt hvis den ikke findes, ellers fjern MongoDB

Det er ikke en god måde at implementere op-stemmer og ned-stemmer. Bortset fra at aggregeringsrammen ikke er en mekanisme til at opdatere dokumenter på nogen måde, ser du ud til at have trukket til at tro, at det kan være en løsning på grund af den logik, du ønsker at implementere. Men aggregat opdateres ikke.

Hvad du vil have på dit, lad os kalde det et "spørgsmål"-skema er en struktur som denne:

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

Det er noget, der kan fungere godt med atomopdateringer og faktisk samtidig give dig nogle statelige oplysninger om objektet.

For "upvoted" og "downvoted"-arrays vil vi overveje, at "brugernes" stemmer har en lignende unik ObjectId-værdi. Så det, vi skal gøre, er $push eller $pull fra enten array og også "øge/nedsætte" tællerværdierne sammen med hver af disse operationer.

Sådan fungerer det for en opstemme:

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

Det er faktisk to operationer, som du kunne gøre med Bulk operations AP Jeg også (sandsynligvis den bedste måde virkelig), men det har en mening med det. Den første sætning vil kun matche et dokument, hvor den aktuelle bruger har en "nedstemme" registreret i arrayet. Som det er, har vi allerede "skubbet" denne bruger-id-værdi til "downvotes"-arrayet. Hvis den ikke er der, foretages der ingen opdatering. Men du både skubber og trækker fra respektive arrays og "øger/nedsætter" også tællerfelterne på samme tid.

Med det andet udsagn, som kun vil matche noget, hvor det første ikke gjorde det, foretager du en retfærdig vurdering af, at nu behøver du ikke røre "nedstemmer" og bare håndtere upvote-felterne. I begge tilfælde er den sikre ting at gøre at sørge for, at hovedbetingelsen er, at den aktuelle bruger-id-værdi ikke er til stede i "upvoted"-arrayet.

For nedstemmer er felterne blot omvendt:

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

Naturligvis kan du se den logiske udvikling til blot at annullere enhver "op-/ned-stemme" for den pågældende bruger. Du kan også være smart med det, hvis du vil og afsløre oplysningerne i din klient for ikke kun at vise, om den aktuelle bruger allerede har "op-/nedstemt", men også kontrollere klikhandlinger og eliminere unødvendige anmodninger.




  1. $expr-forespørgselsoperator ser ikke ud til at fungere med matrixpunktnotation

  2. Spredning af MongoDB på tværs af EC2-regioner

  3. mongodb gruppe og undergruppe tæller

  4. Java MongoDB POST:415 ikke-understøttet medietype