MongoDB使用排序查询结果中的位置来计算字段

时间:2015-02-27 17:19:03

标签: node.js mongodb mongoose

我为用户提供了一个Mongoose模型。每个用户都有一定的积分。我想创建一个用户排名的字段:

rank = user position sorted by rank / total users

假设用户模型如下所示:

{
    'name': 'bob',
    'points': 15,
    'rank': 9/15,
}

(我意识到存储时该分数实际上是小数)。

有没有办法可以通过以下方式更新所有这些用户:

1)按点排序

2)在此排序列表中获取用户索引

3)将该指数除以列表中的项目总数

我不确定是什么类型的mongo运营商可以在查询结果中查找文档的位置以及查找查询结果的总大小。

1 个答案:

答案 0 :(得分:0)

您可以使用几个查询和一些JavaScript来执行此操作。扩展您概述的步骤,您需要做的是:

  1. 查找所有用户文档,按points降序排序,并将结果分配给游标。您可能希望确保在此字段上有索引以使此查询运行得更快。
  2. 获取返回文件数量的计数。
  3. 使用索引跟踪结果中文档的位置。
  4. 遍历文档,使用计数和索引计算rank,并使用该计算结果更新相应用户的rank
  5. mongo shell中,代码看起来如下所示。

    var c = db.user.find().sort({ "points": -1 });
    var count = c.count();
    var i = 1;
    while (c.hasNext()) {
        var rank = i / count;
        var user = c.next();
        db.user.update(
            { "_id": user._id },
            { "$set": { "rank": rank } }
        );
        i++;
    }
    

    因此,如果您的收藏中有以下三个用户:

    {
        "_id" : ObjectId("54f0af63cfb269d664de0b4e"),
        "name" : "bob",
        "points" : 15,
        "rank" : 0
    }
    {
        "_id" : ObjectId("54f0af7fcfb269d664de0b4f"),
        "name" : "arnold",
        "points" : 20,
        "rank" : 0
    }
    {
        "_id" : ObjectId("54f0af95cfb269d664de0b50"),
        "name" : "claus",
        "points" : 10,
        "rank" : 0
    }
    

    更新后,他们的文件将如下所示:

    {
        "_id" : ObjectId("54f0af63cfb269d664de0b4e"),
        "name" : "bob",
        "points" : 15,
        "rank" : 0.6666666666666666
    }
    {
        "_id" : ObjectId("54f0af7fcfb269d664de0b4f"),
        "name" : "arnold",
        "points" : 20,
        "rank" : 0.3333333333333333
    }
    {
        "_id" : ObjectId("54f0af95cfb269d664de0b50"),
        "name" : "claus",
        "points" : 10,
        "rank" : 1
    }