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

Inserisci se non esiste, altrimenti rimuovi MongoDB

Non è un buon modo per implementare voti positivi e negativi. A parte il fatto che il framework di aggregazione non è in alcun modo un meccanismo per aggiornare i documenti, sembra che tu abbia gravitato nel pensare che potrebbe essere una soluzione a causa della logica che vuoi implementare. Ma l'aggregato non si aggiorna.

Quello che vuoi sul tuo, beh, chiamiamolo uno schema di "domanda" è una struttura come questa:

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

Questo è qualcosa che può funzionare bene con gli aggiornamenti atomici e allo stesso tempo darti alcune informazioni stateful sull'oggetto.

Per gli array "upvoted" e "downvoted", considereremo che il voto degli "utenti" ha un valore ObjectId univoco simile. Quindi quello che faremo è $push o $pull da entrambi gli array e anche "incrementa/decrementa" i valori del contatore insieme a ciascuna di queste operazioni.

Ecco come funziona per un voto positivo:

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

In realtà si tratta di due operazioni, che potresti eseguire con l'AP per operazioni in blocco Anch'io (probabilmente il modo migliore in realtà) ma ha ragione. La prima istruzione corrisponderà solo a un documento in cui l'utente corrente ha un "voto negativo" registrato nell'array. In quanto tale, abbiamo già "spinto" quel valore dell'ID utente nell'array "downvotes". Se non è presente, non viene effettuato alcun aggiornamento. Ma entrambi spingi e estrai dai rispettivi array e allo stesso tempo "incrementi/diminuisci" i campi del contatore.

Con la seconda affermazione che corrisponderà solo a qualcosa in cui la prima non lo faceva, fai una valutazione equa che ora non è necessario toccare "downvotes" e gestire solo i campi di upvote. In entrambi i casi la cosa sicura da fare è assicurarsi che la condizione principale sia che il valore dell'ID utente corrente non sia presente nell'array "upvoted".

Per i voti negativi i campi sono semplicemente invertiti:

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

Naturalmente puoi vedere la logica progressione verso la semplice cancellazione di qualsiasi "upvote/downvote" per l'utente in questione. Inoltre puoi essere intelligente se lo desideri ed esporre le informazioni nel tuo client non solo per mostrare se l'utente corrente ha già "votato a favore / declassato", ma anche controllare le azioni dei clic ed eliminare le richieste non necessarie.