MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Einfügen, falls nicht vorhanden, andernfalls MongoDB entfernen

Das ist kein guter Weg, um Upvotes und Downvotes zu implementieren. Abgesehen davon, dass das Aggregationsframework kein Mechanismus zum Aktualisieren von Dokumenten in irgendeiner Weise ist, scheinen Sie sich aufgrund der Logik, die Sie implementieren möchten, zu der Annahme hingezogen zu haben, dass dies eine Lösung sein könnte. Aber Aggregat wird nicht aktualisiert.

Was Sie auf Ihrem, na ja, nennen wir es ein "Frage"-Schema wollen, ist eine Struktur wie diese:

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

Das ist etwas, das gut mit atomaren Aktualisierungen funktionieren kann und Ihnen gleichzeitig einige zustandsbehaftete Informationen über das Objekt liefert.

Für die Arrays „upvoted“ und „downvoted“ werden wir berücksichtigen, dass die „users“-Abstimmung einen ähnlichen eindeutigen ObjectId-Wert hat. Was wir also tun werden, ist $push oder $pull von beiden Arrays und auch die Zählerwerte zusammen mit jeder dieser Operationen "erhöhen/verringern".

So funktioniert das für eine Upvote:

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

Eigentlich sind das zwei Operationen, die Sie mit dem AP für Massenoperationen durchführen könnten Ich auch (wahrscheinlich der beste Weg wirklich), aber es hat einen Sinn. Die erste Anweisung stimmt nur mit einem Dokument überein, in dem der aktuelle Benutzer ein "Downvote" im Array aufgezeichnet hat. Wir haben diesen Benutzer-ID-Wert bereits in das Array "downvotes" "geschoben". Wenn es nicht vorhanden ist, wird keine Aktualisierung vorgenommen. Aber Sie pushen und ziehen von entsprechenden Arrays und "erhöhen/verringern" gleichzeitig die Zählerfelder.

Mit der zweiten Aussage, die nur mit etwas übereinstimmt, wo die erste nicht zutrifft, treffen Sie eine faire Einschätzung, dass Sie jetzt nicht auf „Abwertungen“ tippen und nur die Upvote-Felder bearbeiten müssen. In beiden Fällen ist es sicher, sicherzustellen, dass die Hauptbedingung darin besteht, dass der aktuelle Benutzer-ID-Wert nicht im "Upvoted"-Array vorhanden ist.

Für Downvotes werden die Felder einfach vertauscht:

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

Natürlich können Sie die logische Weiterentwicklung sehen, um einfach jedes "Upvote / Downvote" für den betreffenden Benutzer abzubrechen. Sie können auch schlau sein, wenn Sie möchten, und die Informationen in Ihrem Client anzeigen, um nicht nur anzuzeigen, ob der aktuelle Benutzer bereits "upvoted/downvoted" hat, sondern auch Klickaktionen zu steuern und unnötige Anfragen zu eliminieren.