如何为“喜欢"建模MongoDB的投票系统 [英] How to Model a "likes" voting system with MongoDB

查看:68
本文介绍了如何为“喜欢"建模MongoDB的投票系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在开发移动应用程序.基本上,人们可以发布他们的照片,而关注者可以喜欢Instagram之类的照片.我使用mongodb作为数据库.像instagram一样,一张照片可能会有很多喜欢的地方.因此,将文档用于带有索引的单个赞"似乎是不合理的,因为这会浪费大量内存.但是,我希望用户快速添加一个赞.所以我的问题是如何为喜欢"建模?基本上,数据模型与instagram非常相似,但使用的是Mongodb.

Currently I am working on a mobile app. Basically people can post their photos and the followers can like the photos like Instagram. I use mongodb as the database. Like instagram, there might be a lot of likes for a single photos. So using a document for a single "like" with index seems not reasonable because it will waste a lot of memory. However, I'd like a user add a like quickly. So my question is how to model the "like"? Basically the data model is much similar to instagram but using Mongodb.

推荐答案

无论您如何构建总体文档,基本上都需要满足两点.基本上,这是已经发布其喜欢"的人的计数"和列表"的属性,以确保没有重复的提交.这是一个基本结构:

No matter how you structure your overall document there are basically two things you need. That is basically a property for a "count" and a "list" of those who have already posted their "like" in order to ensure there are no duplicates submitted. Here's a basic structure:

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

无论哪种情况,您的照片张贴"都有一个唯一的"_id",以及您想要的任何信息,但是前面提到的其他字段.这里的喜欢"属性是一个数组,它将保存系统中用户"对象的唯一"_id"值.因此,每个用户"都在本地存储或OpenId或其他地方有自己的唯一标识符,但有一个唯一标识符.我将以ObjectId为例.

Whatever the case, there is a unique "_id" for your "photo post" and whatever information you want, but then the other fields as mentioned. The "likes" property here is an array, and that is going to hold the unique "_id" values from the "user" objects in your system. So every "user" has their own unique identifier somewhere, either in local storage or OpenId or something, but a unique identifier. I'll stick with ObjectId for the example.

当某人向帖子提交赞"时,您要发出以下更新声明:

When someone submits a "like" to a post, you want to issue the following update statement:

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

现在> $inc 操作将通过指定的数字增加"likeCount"的值,因此增加1. $push 操作会将用户的唯一标识符添加到文档中的数组中,以备将来参考.

Now the $inc operation there will increase the value of "likeCount" by the number specified, so increase by 1. The $push operation adds the unique identifier for the user to the array in the document for future reference.

这里最重要的是要记录那些投票的用户以及该语句的查询"部分中发生的情况.除了通过自己的唯一"_id"选择要更新的文档外,另一重要的事情是检查喜欢"数组以确保当前的投票用户还不在该列表中.

The main important thing here is to keep a record of those users who voted and what is happening in the "query" part of the statement. Apart from selecting the document to update by it's own unique "_id", the other important thing is to check that "likes" array to make sure the current voting user is not in there already.

相反的情况或删除""like"也是如此:

The same is true for the reverse case or "removing" the "like":

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

这里最重要的是查询条件,用于确保如果不满足所有条件,则不会触摸任何文档.因此,如果用户已经投票,则该计数不会增加;如果用户在更新时实际上不再显示其投票,则计数不会减少.

The main important thing here is the query conditions being used to make sure that no document is touched if all conditions are not met. So the count does not increase if the user had already voted or decrease if their vote was not actually present anymore at the time of the update.

当然,从应用程序的任何其他部分读取文档中包含数百个条目的数组是不切实际的.但是MongoDB也有一种非常标准的方式来处理该问题:

Of course it is not practical to read an array with a couple of hundred entries in a document back in any other part of your application. But MongoDB has a very standard way to handle that as well:

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

$elemMatch 仅会在当前用户存在的情况下返回当前用户,或者在不存在的情况下仅返回空白用户.这样一来,您的其余应用程序逻辑就可以知道当前用户是否已经投票.

This usage of $elemMatch in projection will only return the current user if they are present or just a blank array where they are not. This allows the rest of your application logic to be aware if the current user has already placed a vote or not.

这是一项基本技术,可能仍然对您有用,但是您应该意识到,嵌入式数组不应无限扩展,并且BSON文档也有16MB的硬限制.因此,这个概念是合理的,但是如果您希望内容中有1000的喜欢票",那么就不能单独使用它.有一个称为存储桶"的概念,此示例在

That is the basic technique and may work for you as is, but you should be aware that embedded arrays should not be infinitely extended, and there is also a hard 16MB limit on BSON documents. So the concept is sound, but just cannot be used on it's own if you are expecting 1000's of "like votes" on your content. There is a concept known as "bucketing" which is discussed in some detail in this example for Hybrid Schema design that allows one solution to storing a high volume of "likes". You can look at that to use along with the basic concepts here as a way to do this at volume.

这篇关于如何为“喜欢"建模MongoDB的投票系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆