Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用Mongoose跳过大量记录时如何避免内存限制?_Mongodb_Indexing_Mongoose - Fatal编程技术网

Mongodb 使用Mongoose跳过大量记录时如何避免内存限制?

Mongodb 使用Mongoose跳过大量记录时如何避免内存限制?,mongodb,indexing,mongoose,Mongodb,Indexing,Mongoose,在拥有超过10万条记录的集合上,当我使用Mongoose选项进行查询时,如下所示: contact.find({}, {}, { collation: { locale: 'en_US', strength: 1 }, skip: 90000, limit: 10, sort: { email: 1 } }); 我得到这个错误: MongoError:find期间执行器错误命令:OperationFailed:排序操作使用的RAM超过最大3355

在拥有超过10万条记录的集合上,当我使用Mongoose选项进行查询时,如下所示:

contact.find({}, {}, {
  collation: {
    locale: 'en_US',
    strength: 1
  },
  skip: 90000,
  limit: 10,
  sort: {
    email: 1
  }
});
我得到这个错误:

MongoError:find期间执行器错误命令:OperationFailed:排序操作使用的RAM超过最大33554432字节。添加索引,或指定较小的限制

但我在电子邮件字段上有一个索引:

{
  "v" : 2,
  "key" : {
    "email" : 1
  },
  "name" : "email_1",
    "ns" : "leadfox.contact",
    "background" : true
}
另一方面,当我在Mongo shell中查询时,它工作正常:

db.contact.find().sort({email: 1}).skip(90000).limit(10)

您所经历的是由于
跳过
。正如你在书中看到的

cursor.skip()方法通常代价高昂,因为它要求服务器在开始返回结果之前,从集合或索引的开头开始遍历以获取偏移量或跳过位置。随着偏移量(例如上面的页码)的增加,cursor.skip()将变得更慢,CPU消耗也更大。对于较大的集合,cursor.skip()可能会被IO绑定

你应该找到一个更好的方法,而不是跳过。当您使用
电子邮件
字段对文档进行排序时,您可以使用电子邮件字段编写一个范围查询,而不是像这样编写
跳过

contact.find({ "email": { $gt: the_last_email_from_previous_query } }, {}, {
  collation: {
    locale: 'en_US',
    strength: 1
  },
  limit: 10,
  sort: {
    email: 1
  }
});
更新:

首先。就像我上面说的,你想要的是不可能的。Mongodb说的,不是我

其次,我建议您搜索现代分页方法和人员用例。你在评论中的例子是荒谬的。任何用户都不应该/不会直接进入第790页查看任何数据。如果他们直接进入这样一个页面,很可能意味着,他们覆盖了数据,直到第790页,他们想继续。因此,即使您正在构建一个无状态系统(就像现在所有的现代系统一样),您也应该为分页数据存储一些关于用户上一个视点的信息。这是一个基于用户行为的示例方法(我不是说最好,它只是一个示例)

另一种方法是,您可以使用(像大多数现代分页表一样),您只允许用户向前或向后导航5-6页。因此,在查询中,您只能跳过50-60个文档,并结合
电子邮件
字段中的
$gt
$lt

另一种方法是使用其他一些工具在内存中缓存数据


我想你明白了。快乐编码。

如果您将电子邮件(指示排序顺序的字段)添加为@Jankapunkt,
email
…FWIW上已经有一个索引,您可以增加MongoDB用于排序操作的内存量:如果您的解决方案有效,那么它对我们的无状态Rest API不起作用。如果用户使用查询参数?page=790将第790页添加为书签,则必须逐页获取到第790页才能获得最终结果,这似乎是错误的。@MaximeSelin建议的解决方案(尽管有点缺陷,因为它仍然包含一个
skip
,不应该再存在了)是MongoDB自己建议使用的地址:记住上一页的最后一个电子邮件地址,并使用该地址执行范围查询。@robertklep我从question复制了查询,但忘记删除
跳过
部分,tnx以提醒。@barbakini感谢您的时间,Mongo给出的错误消息让我感到困惑。有没有关于它为什么在Mongo shell中工作的解释?可能使用具有该shell语法的聚合?