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.