sql >> Databáze >  >> NoSQL >> MongoDB

Vložte, pokud neexistuje, jinak odstraňte MongoDB

To není dobrý způsob, jak implementovat hlasy pro a proti. Kromě toho, že agregační rámec není žádným způsobem mechanismem pro aktualizaci dokumentů, zdá se, že jste si mysleli, že to může být řešení kvůli logice, kterou chcete implementovat. Ale agregát se neaktualizuje.

To, co chcete na svém, řekněme tomu schématu „otázky“, je struktura podobná této:

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

To je něco, co může dobře fungovat s atomickými aktualizacemi a ve skutečnosti vám zároveň poskytne nějaké stavové informace o objektu.

Pro pole „upvoted“ a „downvoted“ budeme uvažovat, že hlasování „uživatelů“ má podobnou jedinečnou hodnotu ObjectId. Takže to, co uděláme, je $push nebo $pull z kteréhokoli pole a také "zvyšovat/snižovat" hodnoty čítače spolu s každou z těchto operací.

Zde je návod, jak to funguje pro souhlas:

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

Ve skutečnosti jsou to dvě operace, které můžete provést pomocí AP pro hromadné operace Já také (pravděpodobně nejlepší způsob), ale má to smysl. První příkaz bude odpovídat pouze dokumentu, ve kterém má aktuální uživatel v poli zaznamenáno „hlasování proti“. Tuto hodnotu ID uživatele jsme již „vtlačili“ do pole „downvotes“. Pokud tam není, aktualizace se neprovádí. Vy však můžete současně tlačit a stahovat z příslušných polí a také „zvyšovat/snižovat“ pole čítače.

S druhým výrokem, který se bude shodovat pouze s něčím, kde první ne, uděláte spravedlivé hodnocení, že nyní nemusíte sahat na „hlasy proti“ a stačí zpracovat pole pro hlasy pro. V obou případech je bezpečné se ujistit, že hlavní podmínkou je, že aktuální hodnota ID uživatele není přítomna v poli „upvoted“.

Pro hlasy proti jsou pole pouze obrácená:

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

Přirozeně můžete vidět logický postup k prostému zrušení jakéhokoli „hlasování proti/hlasování“ pro daného uživatele. Také na to můžete být chytří, pokud chcete a chcete, aby informace ve vašem klientovi nejen ukazovaly, zda aktuální uživatel již „hlasoval proti/hlasoval“, ale také kontroloval akce kliknutí a eliminoval zbytečné požadavky.




  1. Jak převést strukturu objektu JSON na tečkovou notaci?

  2. Existuje při aktualizaci položky nějaký mechanismus zámku v mezipaměti Azure Redis?

  3. Jak aktualizovat více prvků pole v mongodb

  4. zpracování změn jmenného prostoru během deserializace JSON String