【问题标题】:Get document's placement in collection based on sort order根据排序顺序获取文档在集合中的位置
【发布时间】:2014-05-18 21:21:09
【问题描述】:

我是 MongoDB 新手(+Mongoose)。我有一个高分集合,其中的文档如下所示:

{id: 123, user: 'User14', score: 101}
{id: 231, user: 'User10', score: 400}
{id: 412, user: 'User90', score: 244}
{id: 111, user: 'User12', score: 310}
{id: 221, user: 'User88', score: 900}
{id: 521, user: 'User13', score: 103}

+ thousands more...

现在我得到了像这样的前 5 名玩家:

highscores
    .find()
    .sort({'score': -1})
    .limit(5)
    .exec(function(err, users) { ...code... });

这很好,但我也想查询“user12 在高分列表中的位置是什么?”

有可能通过查询以某种方式实现吗?

【问题讨论】:

    标签: javascript mongodb mongoose mapreduce


    【解决方案1】:

    如果您不必实时获得展示位置,Neil Lunn 的答案是完美的。但是,如果您的应用始终在此集合中插入数据,那么对于新数据,您将无法为其获取位置。

    这是另一个解决方案:

    首先,您在此集合中的字段分数上添加索引。然后使用查询db.highscores.count({score:{$gt: user's score})。它将计算得分大于目标的文档。这个数字就是展示位置。

    【讨论】:

      【解决方案2】:

      可以使用mapReduce 执行此操作,但它确实要求您在排序字段上有一个索引,所以首先,如果您还没有这样做:

      db.highscores.ensureIndex({ "score": -1 })
      

      那么你可以这样做:

      db.highscores.mapReduce(
          function() {
              emit( null, this.user );
          },
          function(key,values) {
              return values.indexOf("User12") + 1;
          },
          {
              "sort": { "score": -1 },
              "out": { "inline": 1 }
          }
      )
      

      或者将其更改为您需要返回的信息,而不仅仅是“排名”位置。但由于这基本上是将所有内容放入一个已经按分数排序的大数组中,因此对于任何合理大小的数据,它可能都不是最佳性能。

      更好的解决方案是维护一个单独的“排名”集合,您可以再次使用 mapReduce 定期更新它,即使它不做任何归约:

      db.highscores.mapReduce(
          function() {
              ranking++;
              emit( ranking, this );
          },
          function() {},
          {
              "sort": { "score": -1 },
              "scope": { "ranking": 0 },
              "out": {
                  "replace": "rankings"
              }
          }
      )
      

      然后你可以查询这个集合以获得你的结果:

      db.rankings.find({ "value.user": "User12 })
      

      这样在“rankings”集合的_id 字段中将包含“发出”的排名。

      【讨论】:

      • 感谢您提供非常详细的答案,现在将实施您的两个集合解决方案:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2016-09-12
      • 2012-06-04
      • 2021-09-23
      相关资源
      最近更新 更多