Wie man ein "Gefällt mir" -Stimmsystem mit MongoDB modelliert

9

Momentan arbeite ich an einer mobilen App. Grundsätzlich können Leute ihre Fotos posten und die Follower mögen die Fotos wie Instagram. Ich benutze mongodb als Datenbank. Wie bei Instagram, gibt es viele Likes für einzelne Fotos. Die Verwendung eines Dokuments für ein einzelnes "Gefällt mir" mit Index erscheint daher nicht sinnvoll, da es viel Speicherplatz verschwendet. Ich möchte jedoch, dass ein Benutzer schnell ein Like hinzufügt. Also meine Frage ist, wie man das "Gefällt mir" modelliert? Grundsätzlich ist das Datenmodell ähnlich wie Instagram, aber mit Mongodb.

    
user2914635 18.01.2015, 02:19
quelle

1 Antwort

23

Ganz gleich, wie Sie Ihr Gesamtdokument strukturieren, es gibt grundsätzlich zwei Dinge, die Sie brauchen. Das ist im Grunde eine Eigenschaft von vier "Zählung" und einer "Liste" von denen, die dort bereits "Gefällt mir" gepostet haben, um sicherzustellen, dass keine Duplikate eingereicht werden. Hier ist eine grundlegende Struktur:

%Vor%

Was auch immer der Fall ist, es gibt eine eindeutige "_id" für Ihre "Foto-Post" und welche Informationen Sie wollen, aber dann die anderen Felder wie erwähnt. Die Eigenschaft "Likes" ist hier ein Array, das die eindeutigen "_id" -Werte von den "Benutzer" -Objekten in Ihrem System enthält. Jeder "Benutzer" hat also seine eigene eindeutige Kennung irgendwo im lokalen Speicher oder in OpenId oder so, aber eine eindeutige Kennung. Ich bleibe bei ObjectId für das Beispiel.

Wenn jemand einem Beitrag "Gefällt mir" sendet, möchten Sie die folgende Aktualisierungsanweisung ausgeben:

%Vor%

Jetzt wird sich die $inc Operation erhöhen der Wert von "likeCount" um die angegebene Zahl, also um 1 erhöhen. Die $push -Operation fügt dem Array im Dokument die eindeutige ID für den Benutzer zur zukünftigen Referenz hinzu.

Wichtig ist hier, dass die Benutzer, die abgestimmt haben und was im "Abfrage" -Teil der Anweisung passiert sind, eine Aufzeichnung erhalten. Abgesehen von der Auswahl des zu aktualisierenden Dokuments durch die eigene eindeutige "_id", ist die andere wichtige Sache, das "Likes" -Array zu überprüfen, um sicherzustellen, dass der aktuelle Abstimmungsbenutzer nicht bereits dort ist.

Das Gleiche gilt für den umgekehrten Fall oder "Entfernen" des "Gefällt mir":

%Vor%

Wichtig hierbei ist, dass die Abfragebedingungen verwendet werden, um sicherzustellen, dass kein Dokument berührt wird, wenn alle Bedingungen nicht erfüllt sind. Die Anzahl erhöht sich also nicht, wenn der Benutzer bereits abgestimmt hat, oder sinkt, wenn seine Stimme zum Zeitpunkt des Updates nicht mehr vorhanden war.

Natürlich ist es nicht praktisch, ein Array mit ein paar hundert Einträgen in einem Dokument in einem anderen Teil Ihrer Anwendung zu lesen. Aber MongoDB hat auch einen sehr standardisierten Weg, um damit umzugehen:

%Vor%

Diese Verwendung von $elemMatch in der Projektion wird geben nur den aktuellen Benutzer zurück, wenn sie vorhanden sind, oder nur ein leeres Array, in dem sie nicht vorhanden sind. Dadurch kann der Rest Ihrer Anwendungslogik erkennen, ob der aktuelle Benutzer bereits eine Abstimmung vorgenommen hat oder nicht.

Das ist die grundlegende Technik und kann für Sie so funktionieren, wie Sie ist, aber Sie sollten sich bewusst sein, dass eingebettete Arrays nicht unendlich erweitert werden sollten, und es gibt auch eine harte Grenze von 16 MB für BSON-Dokumente. Das Konzept ist also solide, kann aber nicht alleine verwendet werden, wenn Sie 1000 "Like Votes" für Ihre Inhalte erwarten. Es gibt ein Konzept, das als "Bucketing" bekannt ist und in diesem Beispiel für Hybrides Schema-Design , das eine Lösung zum Speichern einer großen Menge von" Likes "ermöglicht. Sie können sich das hier zusammen mit den grundlegenden Konzepten ansehen, um dies auf Datenträger zu tun.

    
Neil Lunn 18.01.2015, 03:26
quelle