在 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”的键值用于在网站上显示信息,另一个详细的剪辑视图带有userId
、clipId
和timestamp
详细的统计数据。
顺便说一句,如果您需要“票数排名前 10 项”之类的内容,请参阅此question。
【讨论】:
以上是关于在 CouchBase 上获取未经用户投票的帖子的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章