Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为“a”建模;“喜欢”;MongoDB投票系统_Mongodb_Mongodb Query_Data Modeling - Fatal编程技术网

如何为“a”建模;“喜欢”;MongoDB投票系统

如何为“a”建模;“喜欢”;MongoDB投票系统,mongodb,mongodb-query,data-modeling,Mongodb,Mongodb Query,Data Modeling,目前我正在开发一款移动应用程序。基本上,人们可以发布他们的照片,追随者也可以像Instagram一样喜欢这些照片。我使用mongodb作为数据库。像instagram一样,一张照片可能会有很多人喜欢。因此,将文档用于带有索引的单个“like”似乎不合理,因为这将浪费大量内存。但是,我希望用户快速添加一个like。所以我的问题是如何对“喜欢”进行建模?基本上,数据模型与instagram非常相似,但使用的是Mongodb。无论您如何构建整个文档,基本上都需要两件事。这基本上是一个财产的“计数”和“

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

无论您如何构建整个文档,基本上都需要两件事。这基本上是一个财产的“计数”和“名单”的人已经张贴了他们的“喜欢”,以确保没有重复提交。以下是一个基本结构:

{
“_id”:ObjectId(“54bb201aa3a0f26f885be2a3”)
“照片”:“imagename.png”,
“likeCount”:0
“喜欢”:[]
}
不管是什么情况,你的“照片帖子”和你想要的任何信息都有一个唯一的“_id”,但其他字段也一样。这里的“likes”属性是一个数组,它将保存系统中“user”对象的唯一“\u id”值。因此,每个“用户”在某个地方都有自己的唯一标识符,无论是在本地存储中还是在OpenId中,但都是唯一标识符。我将继续使用
ObjectId
作为示例

当某人向帖子提交“like”时,您希望发出以下更新语句:

db.photos.update(
{ 
“_id”:ObjectId(“54bb201aa3a0f26f885be2a3”),
“likes”:{“$ne”:ObjectId(“54bb2244a3a0f26f885be2a4”)}
},
{
“$inc”:{“likeCount”:1},
“$push”:{“likes”:ObjectId(“54bb2244a3a0f26f885be2a4”)}
}
)
现在,那里的操作会将“likeCount”的值增加指定的数字,因此增加1。该操作将用户的唯一标识符添加到文档中的数组中,以供将来参考

这里最重要的事情是记录那些投票的用户,以及在语句的“查询”部分发生了什么。除了通过文档自身唯一的“\u id”选择要更新的文档外,另一个重要的事情是检查“likes”数组,以确保当前投票用户不在其中

相反的情况或“删除”类似的情况也是如此:

db.photos.update(
{ 
“_id”:ObjectId(“54bb201aa3a0f26f885be2a3”),
“likes”:ObjectId(“54bb2244a3a0f26f885be2a4”)
},
{
“$inc”:{“likeCount”:-1},
“$pull”:{“likes”:ObjectId(“54bb2244a3a0f26f885be2a4”)}
}
)
这里最重要的是使用查询条件,以确保在不满足所有条件的情况下不会触动任何文档。因此,如果用户已经投票,则计数不会增加;如果更新时他们的投票不再实际存在,则计数不会减少

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

db.photos.find(
{ 
“_id”:ObjectId(“54bb201aa3a0f26f885be2a3”),
},
{ 
“照片”:1
“likeCount”:1,
“喜欢”:{
“$elemMatch”:{“$eq”:ObjectId(“54bb2244a3a0f26f885be2a4”)}
}
}
)
使用in-projection只会返回当前用户(如果当前用户存在)或仅返回空白数组(如果不存在)。这允许应用程序逻辑的其余部分知道当前用户是否已经进行了投票


这是最基本的技术,可能对您很有用,但您应该知道,嵌入式阵列不应该无限扩展,BSON文档也有16MB的硬限制。因此,这个概念是合理的,但如果你希望在你的内容上获得1000张“赞成票”,就不能单独使用。有一个称为“bucketing”的概念,在本例中对此进行了详细讨论,它允许一个解决方案存储大量的“like”。您可以将其与此处的基本概念结合使用,作为批量操作的一种方法。

您可以为指向照片的每个文档设置一个
likes
字段。并使用
$inc
操作符以原子方式更新每个文档的字段。但是,如果你能发布当前的文档结构并正确地重新表述你的需求,你会得到很好的答案。添加喜欢的内容将非常简单和快速,你可以将所有需要的数据直接传递给服务器,并直接执行一个查询以插入数据库。但是,您将需要缓存和聚合like计数,因为计算这些like会很麻烦。大多数网站,包括instagram,都使用计数器,比如@Batshray说使用$inc(或者他们使用的技术中存在的任何东西)来缓存likes的存在,这样就可以很容易地说出有多少likes有很好的答案,很抱歉提出这个问题,但是你对实施这样的解决方案有什么想法(而不是使用子文档保存赞成票或投票)@disper这里的总体思路是尽可能简单地检查某人是否投票,并在不进行聚合的情况下读取总票数,或者至少通过拆分成尽可能少的文档。其他模型要么依赖于实时聚合,要么在更新方面不具原子性。快速写入,快速读取。对于通常是您想要的高活动项目。@Neil Lunn。谢谢您的回答。实际上,我的数据结构与您的非常相似,我计划使用bucketing设计。我想知道使用$elemMatch运算符查找大量喜欢的内容的性能有多好。假设有300000张喜欢的照片,我有300个buc每个桶包含1000个喜欢。知道当前用户是否有alre有效吗