Cómo modelar un sistema de votación de “me gusta” con MongoDB

Actualmente estoy trabajando en una aplicación móvil. Básicamente, las personas pueden publicar sus fotos y los seguidores pueden ver fotos como Instagram. Yo uso mongodb como la base de datos. Al igual que instagram, puede haber muchos “Me gusta” para una sola foto. Entonces, usar un documento para un solo “me gusta” con índice no parece razonable porque perderá mucha memoria. Sin embargo, me gustaría que un usuario agregue un me gusta rápidamente. ¿Entonces mi pregunta es cómo modelar el “me gusta”? Básicamente, el modelo de datos es muy similar a Instagram pero usando Mongodb.

No importa cómo estructure su documento general, hay básicamente dos cosas que necesita. Eso es básicamente una propiedad cuatro un “recuento” y una “lista” de aquellos que ya han publicado “me gusta” para asegurarse de que no se envíen duplicados. Aquí hay una estructura básica:

 { "_id": ObjectId("54bb201aa3a0f26f885be2a3") "photo": "imagename.png", "likeCount": 0 "likes": [] } 

En cualquier caso, hay un “_id” único para su “publicación fotográfica” y la información que desee, pero luego los otros campos como se menciona. La propiedad “Me gusta” aquí es una matriz, y eso mantendrá los valores únicos “_id” de los objetos de “usuario” en su sistema. Entonces, cada “usuario” tiene su propio identificador único en alguna parte, ya sea en almacenamiento local o OpenId o algo así, pero un identificador único. Me quedaré con ObjectId para el ejemplo.

Cuando alguien envía un “me gusta” a una publicación, desea emitir la siguiente statement de actualización:

 db.photos.update( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), "likes": { "$ne": ObjectId("54bb2244a3a0f26f885be2a4") } }, { "$inc": { "likeCount": 1 }, "$push": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") } } ) 

Ahora, la operación $inc boostá el valor de “likeCount” en el número especificado, por lo tanto, incremente en 1. La operación $push agrega el identificador único para el usuario a la matriz en el documento para referencia futura.

Lo más importante aquí es mantener un registro de los usuarios que votaron y lo que está sucediendo en la parte de “consulta” de la statement. Además de seleccionar el documento para actualizar por su propio “_id” único, la otra cosa importante es verificar esa matriz de “me gusta” para asegurarse de que el usuario actual no esté allí.

Lo mismo es cierto para el caso inverso o “eliminar” el “me gusta”:

 db.photos.update( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), "likes": ObjectId("54bb2244a3a0f26f885be2a4") }, { "$inc": { "likeCount": -1 }, "$pull": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") } } ) 

Lo más importante aquí son las condiciones de consulta que se utilizan para garantizar que no se toque ningún documento si no se cumplen todas las condiciones. Por lo tanto, el recuento no aumenta si el usuario ya había votado o disminuido si su voto ya no estaba presente en el momento de la actualización.

Por supuesto, no es práctico leer una matriz con un par de cientos de entradas en un documento en cualquier otra parte de su aplicación. Pero MongoDB tiene una forma muy estándar de manejar eso también:

 db.photos.find( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), }, { "photo": 1 "likeCount": 1, "likes": { "$elemMatch": { "$eq": ObjectId("54bb2244a3a0f26f885be2a4") } } } ) 

Este uso de $elemMatch en proyección solo devolverá al usuario actual si están presentes o solo una matriz en blanco donde no lo están. Esto permite que el rest de la lógica de la aplicación tenga en cuenta si el usuario actual ya ha votado o no.

Esa es la técnica básica y puede funcionar para usted tal como es, pero debe tener en cuenta que las matrices integradas no deben extenderse infinitamente, y también existe un límite de 16 MB en documentos BSON. Entonces, el concepto es sólido, pero no se puede usar solo si esperas 1000 de “me gusta” en tu contenido. Existe un concepto conocido como “cubicación” que se analiza con cierto detalle en este ejemplo para el diseño de Esquema Híbrido que permite que una solución almacene un gran volumen de “Me gusta”. Puede ver eso para usar junto con los conceptos básicos aquí como una forma de hacerlo en el volumen.

    Intereting Posts