在 CouchBase 上获取未经用户投票的帖子的最有效方法是啥?

Posted

技术标签:

【中文标题】在 CouchBase 上获取未经用户投票的帖子的最有效方法是啥?【英文标题】:What is the most efficient approach to get posts that were not voted by an user, on CouchBase?在 CouchBase 上获取未经用户投票的帖子的最有效方法是什么? 【发布时间】:2013-06-22 17:17:29 【问题描述】:

我有一个包含以下格式的帖子的存储桶:

title:"foo", 
description:"bar", 
votes: John:1, Leo:-1, ...

我将不断查询投票数少于 N 且尚未由特定用户投票的帖子。问题是:我不能为每个特定用户创建视图,所以我必须设置一个来过滤

【问题讨论】:

为什么要在某个对象中保存选票?在您的情况下是否可以为每个用户保存选票(可能会更容易和更有用):"type":"vote", "voterId":123, "votedForId": 1 并拥有"type":"item","title":"foo"。如果你使用你的方法,你应该处理“同时”投票,如果有很多用户可以投票,这可能会成为一个问题。 @Alex Uh huh,这让我感到困惑:我认为我实际上应该避免像这样分离对象。那就更好了。但我真的需要一个包含这些东西的指南/教程!有很多(简单的)事情不清楚,我在官方文档中并没有真正找到!是的,有很多用户可以投票。整个事情实际上只是一个页面,您可以在其中尽可能快地连续投票。 【参考方案1】:

如果您有许多可以投票的用户,则不应使用您的方法,因为要添加投票,您需要:

    获取文档 将 json 解析成某种结构 为投票数组添加一些投票 将对象写回基础

因此,如果其他人在 1 到 4 步之间投票,而您在回信时没有检查 CAS,则该投票将丢失。如果您检查CAS 并且投票来得非常快,那么您可能会获得非常慢的性能。

正如我之前所说,解决方案是在 JSON 中单独保存选票,例如:


  "type":"vote",
  "voterId": 123,
  "votedFor": 321,
  "timestamp": 131321321

并在没有投票的情况下存储您的项目,如下所示:


  "type":"item",
  "itemId": 321,
  "title": foo

使用此方案,您仅在需要计算投票时才使用投票,查看用户对某些项目的投票等。

另一个技巧:如果您需要显示投票,即在您的网站上,您还可以使用“fast_voutes_count”。这意味着您可以创建单独的变量来仅存储每个项目的投票数:votes:count:for:<itemId>。如果有人投票,您应该:

    按键增加项目投票计数值:votes:count:for:<itemId> 将用户的投票存储为投票文档 ("type":"vote","voterId": 123,"votedFor": 321, "timestamp": 131321321)。

所以第一个值将用于在网站上显示投票。第二个将用于统计您的统计数据。

要创建您需要的视图(map、reduce 函数),您可以参考此manual 及其示例。如果您不熟悉 map/reduce,请首先尝试创建一个仅显示特定 itemId 投票的视图,这是一个小示例:

map: 
function()
  if (meta.type === "json" && doc.type === "vote")
    emit(doc.votedFor, null);
  

然后,如果您想计算(总和)投票,只需使用 _count 作为 reduce 函数。

PS:在我的应用程序中,我们使用这种方法来计算视频的观看次数:一个名为“fast_clip_view”的键值用于在网站上显示信息,另一个详细的剪辑视图带有userIdclipIdtimestamp详细的统计数据。

顺便说一句,如果您需要“票数排名前 10 项”之类的内容,请参阅此question。

【讨论】:

以上是关于在 CouchBase 上获取未经用户投票的帖子的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Hasura:允许用户不为自己的帖子投票

无法弄清楚“一旦10个用户喜欢它就批准帖子”的系统

在 laravel 中获取此操作是未经授权的

解决tableView中的重复单元格

Discord Bot- 使用 YAGPDB bot 的反应投票

在投票前用设计用户登录的rails博客投票系统