【问题标题】:How to efficiently page batches of results with MongoDB如何使用 MongoDB 高效地对批量结果进行分页
【发布时间】:2023-04-01 14:35:01
【问题描述】:

我在我的 MongoDB 集合上使用以下查询,这需要一个多小时才能完成。

db.collection.find({language:"hi"}).sort({_id:-1}).skip(5000).limit(1)

我试图在一批 5000 中获取结果,以便按升序或降序处理语言字段中具有“hi”作为值的文档。所以我使用这个查询,每次通过增加“skip”值来跳过处理过的文档。

此集合中的文档数量刚刚超过 2000 万。 “语言”字段的索引已创建。 我使用的 MongoDB 版本是 2.6.7

这个查询有没有更合适的索引可以更快的得到结果?

【问题讨论】:

  • 并非如此。你“应该”问的是“有没有更好的方法来分页我的结果”并解释你的实际用例而不是假设的用例。
  • 我正在尝试获取一批 5000 的结果,以便在语言字段中以“hi”作为值的文档按升序或降序处理。所以我正在使用这个查询,我每次都通过增加“跳过”值来跳过处理过的文档。
  • 那里。现在看看你问的问题有多少描述性。请编辑您的问题以包含该内容以及更合适的标题。这是个好问题。你问的是一个可怕的问题。所以你一次只想要 5000 个,然后继续下一批,以此类推,对吗?
  • 是的,你完全正确。
  • 为您编辑。当你没有问正确的问题时,看看你得到的答案。这是一个例子。是的,有一个解决方案。给我一点时间。

标签: mongodb mongodb-query


【解决方案1】:

当您想要降序排序时,您应该创建一个多字段索引,该索引使用您排序的字段作为降序字段。您可以通过将这些字段设置为 -1 来做到这一点。

这个索引应该会大大提高你的排序性能:

db.collection.ensureIndex({ language: 1, _id: -1 });

如果您还想加快其他情况 - 检索按升序排序 - 创建第二个索引,如下所示:

db.collection.ensureIndex({ language: 1, _id: 1 });

请记住,当您不对结果进行排序时,您会按自然顺序收到它们。自然顺序是经常插入顺序,但不能保证这一点。有各种事件会导致自然顺序混乱,因此当您关心顺序时,您应该始终明确排序。此规则的唯一例外是 capped collections,它始终保持插入顺序。

【讨论】:

    【解决方案2】:

    为了以您想要的方式有效地“分页”结果,最好使用“范围查询”并保留您处理的最后一个值。

    你想要的“排序键”是_id,这样就很简单了:

    首先,您希望索引以正确的顺序使用 .createIndex() 完成,这不是已弃用的方法:

    db.collection.createIndex({ "language": 1, "_id": -1 })
    

    那你想做一些简单的处理,从头开始:

    var lastId = null;
    
    var cursor = db.collection.find({language:"hi"});
    cursor.sort({_id:-1}).limit(5000).forEach(funtion(doc) {
        // do something with your document. But always set the next line
        lastId = doc._id;
    })
    

    这是第一批。现在,当您继续下一个时:

    var cursor = db.collection.find({ "language":"hi", "_id": { "$lt": lastId });
    cursor.sort({_id:-1}).limit(5000).forEach(funtion(doc) {
        // do something with your document. But always set the next line
        lastId = doc._id;
    })
    

    以便在进行选择时始终考虑lastId 值。您在每批之间存储它,然后从最后一个继续。

    这比使用.skip() 处理效率高得多,无论索引如何,它都“仍然”需要“跳过”集合中的所有数据直到跳过点。

    在此处使用 $lt 运算符“过滤”您已处理的所有结果,因此您可以更快地进行操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-20
      • 2017-07-02
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多