如何在mongodb / mongoose查询中改变基于参数的结果位置

How to change result position based off parameter in a mongodb / mongoose query?

本文关键字:于参数 参数 位置 结果 改变 mongodb mongoose 查询      更新时间:2023-09-26

所以我使用猫鼬和node.js访问mongodb数据库。我想根据一个数字增加每个结果(如果没有增加,则按创建日期排序)。例如:

{ name: 'A',
  bump: 0 },
{ name: 'B',
  bump: 0 },
{ name: 'C',
  bump: 2 },
{ name: 'D',
  bump: 1 }

将按顺序检索:C, A, D, b。这如何实现(不遍历数据库中的每个条目)?

试试这样做。存储一个跟踪线程总数#的计数器,我们称其为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排序为ASCENDING,并且它将按照最老到最新的顺序返回它们(或从最新到最老的降序)。

然后要"碰撞"一个线程的排序顺序,当它被投票,你可以用{$inc:{post_order:1}}调用update()的文档。这将使它在结果排序的顺序上提前1。如果两个线程的post_order值相同,created_at将区分哪个先出现。因此,您将按post_order, created_at排序。

您将需要在post_ordercreated_at上有一个索引

让我们猜测您的代码是变量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;
});

不是一个令人愉快的答案,但是您要求的解决方案是不现实的。我的建议是:

  1. 为你的对象添加OrderPosition属性,而不是Bump

  2. 把"碰撞"想象成一个事件。最好将其表示为事件处理程序函数。当一个项被业务逻辑中的任何触发器"碰撞"时,需要调整项的集合。

    var currentOrder = this.OrderPosition
    this.OrderPosition = currentOrder - bump;  // moves your object up the list
    // write a foreach loop here, iterating every item AFTER the items unadjusted
    // order, +1 to move them all down the list one notch.    
    

这确实需要迭代许多项,我知道您试图阻止这种情况,但我不认为有任何其他方法可以安全地确保项排序的完整性-特别是相对于稍后发生的其他拉取集合。

我不认为纯基于查询的解决方案是可能与您的文档模式(我假设您有createdDatebump字段)。相反,我建议使用一个名为sortorder的字段来跟踪所需的检索顺序:

  1. sortorder是初始创建时间戳。如果没有"凸起",则按此字段排序会给出正确的顺序。
  2. 如果有"bump",则sortorder无效。所以只需纠正sortorder值:每次发生"碰撞"时,交换碰撞文档的sortorder字段和它直接前面的文档。这实际上是在排序顺序上"凸起"文档。
  3. 查询时按sortorder排序

您可以删除bumpcreatedDate字段,如果它们不在其他地方使用。


说句题外话,大多数社交网站不会根据投票数(或"访问量")直接操纵帖子的显示位置。相反,投票数是用来计算分数的。然后根据这个分数对帖子进行排序和显示。在您的示例中,应该将createdDatebumps组合成一个分数,以便可以在查询中对进行排序。

这个网站(StackOverflow.com)有一个关于如何确定"热门"问题的相关元讨论。我想甚至还会有一场竞赛来想出一个新的配方。这个元问题还分享了另外两个流行的社会新闻网站:Y Combinator Hacker news和Reddit使用的公式。