在查询的时候用mongoose来降低内存使用的方法

我正在研究节点后端,试图通过mongoose来优化对mongodb的非常大的查询。 预期的返回大小是相当可观的,但是由于某种原因,当我发出请求时,节点开始消耗大量的内存,例如200MB +用于一个大的请求。

考虑到大多数情况下,回报的规模小于10mb,这似乎并不正确。 在完成之后,它也拒绝释放内存,我知道这可能只是V8 GC的默认行为,但是我担心的是,单个find()请求会消耗大量的内存。

我通过testingfind()调用来隔离它。 一旦完成了调用,它将执行一些后处理,然后将数据发送到一个callback函数,全部使用匿名函数。 我曾尝试使用查询stream而不是model.find(),但它显示没有真正的改进。

环顾四周没有得到任何回应,所以我会问,有没有一种已知的方法来减less,控制或优化mongoose的内存使用? 有谁知道为什么如此多的内存被用于一个单一的电话?

编辑

根据Johnny和Blakes的build议,使用lean()和streaming的混合,并使用暂停和恢复,极大地改善了运行时和内存的使用。 谢谢!

只要您只需要普通的JavaScript文档而不需要完整的Mongoose文档实例,就可以使用精简选项来使用Mongoose查询。 这样可以提高性能并减less内存使用量。

 model.find().lean().exec(function(err, docs) {...}); 

您还可以将lean()与stream式传输结果相结合,从而进一步减less内存使用量。

 var stream = model.find().lean().stream(); 

默认.find()当然会返回所有的结果作为一个“数组”,所以总是要使用大量结果的内存,所以这留下了“stream”接口。

这里的基本问题是你正在使用一个stream接口(因为这是从基本节点streaminheritance的),每个数据事件“触发”并且相关的事件处理程序连续执行。

这意味着,即使对于“stream”,事件处理程序中的后续操作也是“堆栈”的,至less消耗大量内存,并且如果在那里进一步发生asynchronous进程,可能会吃掉调用堆栈。

所以你可以做的最好的事情就是开始“限制”stream处理中的操作。 这和调用.pause()方法一样简单:

 var stream = model.find().stream(); // however you call stream.on("data",function() { // call pause on entry stream.pause(); // do processing stream.resume(); // then resume when done }); 

所以.pause()停止正在发送的stream中的事件,这样可以让事件处理程序中的动作在继续之前完成,以便它们不会一次全部到达。

当你的处理代码完成的时候,你可以直接在块内执行.resume() ,如图所示,在块内执行的任何asynchronous操作的callback块中。 请注意,同样的规则适用于asynchronous操作,并且在调用简历之前,“全部”必须表示完成。

还有其他的优化方法可以应用,你可能会希望看到一个“队列处理”或“asynchronousstream控制”可用的模块,以帮助你通过一些并行的执行来获得更多的性能。

但基本上可以这样认为.pause()然后处理和.resume()继续避免在处理中占用大量内存。

另外,要注意你的“输出”,并且同样尝试再次使用一个“stream”,如果build立一些响应。 如果你所做的工作实际上只是在内存中build立另一个variables,所有这一切都将毫无用处,所以有助于了解这一点。