草庐IT

mongodb - 用户评分模式 - 键/值数据库

coder 2023-05-04 原文

我们正在使用 MongoDB,我正在寻找一种用于存储评级的架构。

  • 评分的值为 1-5。
  • 我想存储其他值,例如 fromUser

这很好,但我的主要问题是设置它,以便重新计算平均值尽可能高效。


解决方案 1 - 单独的评级等级

首先想到的是创建一个单独的Ratings类并存储指向 Ratings 的指针数组在 User类(class)。我第二次猜测的原因是我们必须查询所有 Ratings每次新的对象Rating进来,以便我们可以重新计算平均值

...

解决方案 2 - 用户类中的字典

第二个想法是将字典存储在 User 中。直接存储这些 Ratings 的类对象。这将比解决方案 1 更轻量级,但我们将重写整个 Ratings每次更新时每个用户的历史记录。这似乎很危险。

...

解决方案 3 - 用户类中具有单独平均值的单独评级类

我们有 Ratings 的混合选项在他们自己的类中,以及指向他们的指针数组,但是,我们在用户类中保留了两个值 - ratingsAveratingsCount .这样,当设置新的评级时,我们会保存该对象,但我们可以重新计算 ratingsAve很容易。


解决方案 3 对我来说听起来最好,但我只是想知道我们是否需要通过重新查询评级历史来重置 ratingsAve 来包括定期校准。只是为了确保一切正常。

我可能想多了,但我不擅长创建数据库架构,这似乎是一个标准架构问题,我应该知道如何实现。

哪个是确保一致性和重新计算效率的最佳选择?

最佳答案

首先,“用户类中的字典”不是一个好主意。为什么?添加额外的速率对象需要向数组推送一个新项目,这意味着旧项目将被删除,这种插入就是所谓的“移动文档”。移动文档很慢,而且 MongoDB 不擅长重用空白空间,因此大量移动文档会导致大量空数据文件(《MongoDB The Definitive Guide》一书中的一些文字)。

那么正确的解决方案是什么:假设您有一个名为 Blogs 的集合,并希望为您的博客文章实现评级解决方案,并另外跟踪每个基于用户的评级操作。

博客文档的架构如下:

{
   _id : ....,
   title: ....,
   ....
   rateCount : 0,
   rateValue : 0,
   rateAverage: 0
}

您需要具有此文档架构的另一个集合(Rates):

{
    _id: ....,
    userId: ....,
    postId:....,
    value: ..., //1 to 5
    date:....   
}

你需要为它定义一个合适的索引:

db.Rates.ensureIndex({userId : 1, postId : 1})//非常有用。如果您想检查用户之前是否对帖子进行过评分,这将导致更快的搜索操作

当用户想要评分时,首先您需要检查用户是否对帖子进行评分。假设用户是 'user1',那么查询将是

var ratedBefore = db.Rates.find({userId : 'user1', postId : 'post1'}).count()

并且基于 ratedBefore,如果 !ratedBefore 则插入新的 rate-document 到 Rates 集合并更新博客状态,否则,用户不允许评分

if(!ratedBefore)
{
    var postId = 'post1'; // this id sould be passed before by client driver
    var userId = 'user1'; // this id sould be passed before by client driver
    var rateValue = 1; // to 5
    var rate = 
    {       
       userId: userId,
       postId: postId,
       value: rateValue,
       date:new Date()  
    };

    db.Rates.insert(rate);
    db.Blog.update({"_id" : postId}, {$inc : {'rateCount' : 1, 'rateValue' : rateValue}});
}

那么 rateAverage 会发生什么? 我强烈建议在客户端根据 rateCountrateValue 计算它,使用 mongoquery 更新 rateAverage 很容易>,但你不应该这样做。为什么?简单的答案是:对于客户来说,处理这类工作是一项非常容易的工作,并且对每个博客文档进行平均需要进行不必要的更新操作。

平均查询将被计算为:

var blog = db.Blog.findOne({"_id" : "post1"});
var avg = blog.rateValue / blog.rateCount;
print(avg);

通过这种方法,您将获得 mongodb 的最大性能,并且您可以根据用户、帖子和日期跟踪每个速率。

关于mongodb - 用户评分模式 - 键/值数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26914380/

有关mongodb - 用户评分模式 - 键/值数据库的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  6. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  7. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  8. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  9. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐