【问题标题】:Mongo error when using aggregation: sort exceeded memory limit使用聚合时的 Mongo 错误:排序超出内存限制
【发布时间】:2014-10-15 05:21:08
【问题描述】:

当我使用聚合排序时,我收到了带有错误代码 16819 的 mongo 错误 exceeded memory limit

我正在使用 mongo 2.6。

查询如下:

db.BASE_TABLE_CREATION_ExecuteHiveScript_26_V0.aggregate([
     { "$project" : { "visitor_localdate" : 1 , "_id" : 0}}, 
     { "$sort" : { "visitor_localdate" : -1}}
])

【问题讨论】:

    标签: mongodb aggregation-framework memory-limit


    【解决方案1】:

    默认情况下,MongoDB 中的聚合发生在内存中,流水线阶段的 RAM 限制为 100 Mb。看起来你已经超过了这个阈值。要处理大型数据集,您应该启用聚合管道阶段以将数据写入临时文件。为此使用allowDiskUse 选项:

    db.BASE_TABLE_CREATION_ExecuteHiveScript_26_V0.aggregate([
        { "$project" : { "visitor_localdate" : 1 , "_id" : 0}},
        { "$sort" : { "visitor_localdate" : -1}}
    ], { "allowDiskUse" : true })
    

    【讨论】:

    • 嗨,谢尔盖,我试过了。它起作用了..我得到了同样的异常。
    • @acube 确保你真的尝试过这个。如果你看一下 mongodb 的 github 源代码,你会发现 MongoDB Error Codes16819 代码有非常清晰的解释注释和解决步骤:排序超出了字节的内存限制,但没有选择外部排序。中止操作。传递 allowDiskUse:true 以选择加入。
    • 当使用猫鼬时使用这个。 db.BASE_TABLE.aggregate([]).allowDiskUse(true);
    • 见下面索尼娅的回答。虽然这可行,但如果您可以在管道中更早地移动排序以便 MongoDb 可以利用索引,则查询首先不需要内存排序。这将使其在大型数据集上的性能更高。
    【解决方案2】:

    如果您使用聚合查询。在您排序的字段上放置一个索引,然后使用排序运算符。

    注意: 将排序运算符放在管道的开头或 $project、$unwind 和 $group 聚合运算符之前。如果 $project、$unwind 或 $group 在 $sort 操作之前发生,则 $sort 不能使用任何索引。 [https://docs.mongodb.com/manual/reference/operator/aggregation/sort/][1]

    【讨论】:

    • 谢谢你,另一件事是对于大型数据集,做流并暂停恢复你的流
    • 感谢您的注意,我遇到了在排序之前运行 unwind 的确切问题,并且一直收到此错误。交换它们修复它!
    • 哇,这是一个很棒的见解。谢谢
    【解决方案3】:

    在聚合管道之后使用{ allowDiskUse: true },如下所示:

    db.collectionOrView.aggregate([], { allowDiskUse: true });
    

    【讨论】:

      【解决方案4】:

      您根本不需要聚合。使用查询

      db.BASE_TABLE_CREATION_ExecuteHiveScript_26_V0.find({}, { "_id" : 0, "visitor_localdate" : 1 }).sort({ "visitor_localdate" : -1 })
      

      并在visitor_localdate 上添加索引。这比聚合更简单、更快捷。

      【讨论】:

      • 我收到此错误:-“errmsg”:“查找命令期间的执行程序错误:OperationFailed:排序操作使用的 RAM 超过了最大 33554432 字节。添加索引或指定更小的限制。 ",
      【解决方案5】:

      要修复它,请在查询中启用 allowDiskUse 选项:

      解决办法

      参考:内存限制

      在 MongoDB 中,in-sort 的最大内存限制为 100M,如果执行更大的排序,则需要使用 allowDiskUse 选项将数据写入临时文件进行排序。

      在查询中添加 allowDiskUse 选项:

      db.bigdata.aggregate(
      [
       {$group : {_id : "$range", total : { $sum : 1 }}},
       {$sort : {total : -1}}
      ],
       {allowDiskUse: true}
      );
      

      【讨论】:

        【解决方案6】:

        在我的场景中,我通过为排序列添加索引来修复它

        【讨论】:

        • 这对我有用
        【解决方案7】:

        对于那些寻找 pymongo

        答案的人

        并获得AttributeError: 'dict' object has no attribute '_txn_read_preference'

        这行得通:

        db.coll.aggregate([], allowDiskUse=True)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-14
          • 1970-01-01
          • 2023-02-17
          • 2016-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-25
          相关资源
          最近更新 更多