所以我使用mongoose和node.js来访问mongodb数据库。我想根据一个数字来提升每个结果(如果没有提升,则按创建日期排序)。例如:
{ name: 'A',
bump: 0 },
{ name: 'B',
bump: 0 },
{ name: 'C',
bump: 2 },
{ name: 'D',
bump: 1 }
将按以下顺序检索: C,A,D,B。如何才能做到这一点(不迭代数据库中的每个条目)?
发布于 2012-01-13 23:42:36
试试这样的东西。存储一个跟踪线程总数的计数器,我们称它为thread_count
,初始设置为0,因此在某个地方有一个类似于{thread_count:0}
的文档。
每次创建新线程时,首先使用{$inc : {thread_count:1}}
作为修饰符调用findAndModify()
-即,将计数器递增1并返回其新值。
然后,当您插入新线程时,使用计数器的新值作为其文档中某个字段的值,我们称其为post_order
。
因此,每次插入的每个文档都有一个大1的值。例如,您插入的前3个文档将如下所示:
{name:'foo', post_order:1, created_at:... } // value of thread_count is at 1
、{name:'bar', post_order:2, created_at:... } // value of thread_count is at 2
、{name:'baz', post_order:3, created_at:... } // value of thread_count is at 3
等。
因此,您可以有效地按post_order
升序查询和排序,它将按最旧到最新的顺序返回它们(或从最新到最旧的降序)。
然后,当一个线程被提升时,为了“颠倒”它的排序顺序,您可以用{$inc:{post_order:1}}
在文档上调用update()
。这将使它在结果排序的顺序中前进1。如果两个线程的post_order值相同,created_at将区分哪个线程先出现。因此,您将按post_order, created_at
进行排序。
你需要在post_order
和created_at
上建立一个索引。
发布于 2012-01-07 05:57:45
假设您的代码是变量response
(一个数组),那么我将这样做:
response.sort(function(obj1, obj2){
return obj2.bump - obj1.bump;
});
或者,如果你还想记住名字的顺序:
response.sort(function(obj1, obj2){
var diff = obj2.bump - obj1.bump;
var nameDiff = (obj2.name > obj1.name)?-1:((obj2.name < obj1.name)?1:0);
return (diff == 0) ? nameDiff : diff;
});
发布于 2012-01-10 16:20:00
对于您的文档模式,我认为纯粹基于查询的解决方案是不可能的(我假设您有createdDate
和bump
字段)。相反,我建议使用一个名为sortorder
的字段来跟踪所需的检索顺序:
sortorder
最初是创建时间戳。如果没有“凹凸”,则按此字段排序会给出正确的顺序。sortorder
无效。因此,只需更正sortorder
值:每次发生“凹凸”时,交换凹凸文档的sortorder
字段和紧靠其前面的文档。这实际上会在排序顺序中“提升”文档。sortorder
.排序
如果字段bump
和createdDate
不在其他地方使用,则可以将其删除。
顺便说一句,大多数社交网站不会直接根据帖子的票数(或“凸起”)来操纵帖子的显示位置。取而代之的是,票数被用来计算分数。然后,根据该分数对帖子进行排序和显示。在您的例子中,您应该将createdDate
和bumps
组合成一个可以在查询中排序的分数。
这个网站(StackOverflow.com)有一个关于如何确定“热门”问题的相关meta discussion。我认为甚至有一场比赛是为了拿出一个新的公式。元问题还分享了其他两个流行的社交新闻网站使用的公式:Y Combinator Hacker news和Reddit。
https://stackoverflow.com/questions/8736974
复制