如何在redis中构建1级嵌套注释?

问题描述:

我一直在努力寻找嵌套评论的数据结构(只有1层的嵌套,例如脸书)如何在redis中构建1级嵌套注释?

为了实现评论的非嵌套“饲料”我一直在使用有序集跟踪评论,将评分作为时间戳和成员用作json编码的一组属性,其中包含呈现评论所需的所有信息。

所以添加注释可能是这样的:

zadd 'users:1:comments', 123456789, {body : 'hello'} 

和检索它是如此简单:

zrevrange 'users:1:comments', 0, 20 

为了支持嵌套评论我一直在努力,在这个扩大在某种程度上 我已经头脑风暴两种不同的方式,但每个都有问题:

1)

添加到COMMENT_ID属性的列表,COMMENT_ID指向父评论

zadd 'users:1:comments', 123456789, {id : 1, body : 'hello'} 
zadd 'comments:1:comments', 123456789, {id : 2, body : 'nested hello', comment_id : 123 } 

应该是这样的:

-hello 
    -nested hello 

这种方法的问题是,当涉及到分页。如果评论有20个嵌套评论,而我只显示前10个评论,则嵌套树将被截断(父评论+ 9嵌套评论将被检索)

2)

把嵌套评论到它自己的饲料:

This is a parent comment 
zadd 'users:1:comments', 123456789, {id: 1, body : 'hello'} 
this is a nested comment 
zadd 'comments:1:comments' 123456789, {id: 2, body : 'nested hello'} 

然而,这将导致N + 1个Redis的查询试图显示用户的饲料时:​​

zrevrange 'users:1:comments', 0, 20 
zrevrange 'comments:1:comments', 0, 20 
zrevrange 'comments:2:comments', 0, 20 
etc... 

...不至 提到嵌套注释可能不应该用范围来选择。

理想情况下,我希望这可以与单个redis查询一起工作,但我不确定如何构建我的数据以便可能。

想法?

我能想出的唯一方法就是使用Lists来得到单个redis查询。

添加父项时,您可以将LPUSH简单地置于列表的顶部(左侧)。当添加一个孩子的评论,你会使用像LINSERT 'user:1:comments' AFTER parent-comment-data child-comment-data

这会导致redis搜索父注释数据并将子数据立即放在其后面。这是一个O(N)操作,并在顶部(左侧)到底部(右侧)完成,因此父表的下一级父母是该操作需要的时间越长,因此对于极其长列表,这可能证明存在问题(但如果您将列表/线程大小保持在4或5位数范围内,应该没问题)。

然后,一个简单的LRANGE可以获取最新的评论,父母和孩子,只限于任何数量。

您可以使用排序集中的分数值做类似的事情,给孩子的分数低于父母。不过,这可能会使插入操作复杂化,因为您可能会耗尽两个父注释之间的可用分数,这意味着您必须运行操作才能为许多(或甚至大部分)注释重新分配分数。如果每次插入都发生这种情况,您的插入可能会(不必要地)成本高昂。

+0

很确定这不能解决我在原帖的#1中描述的分页问题。 – jsharpe