【问题标题】:"$push used too much memory and cannot spill to disk. Memory limit: 104857600 bytes"“$push 使用了太多内存,无法溢出到磁盘。内存限制:104857600 字节”
【发布时间】:2020-01-21 14:19:31
【问题描述】:

我正在从应用程序发送获取请求并收到以下错误:

{"$push used too much memory and cannot spill to disk. Memory limit: 104857600 bytes"}

我正在使用具有 4GB 内存和 20GB 存储空间的 atlas 托管 mongo-db。我想,我需要更新一些配置设置,但我缺少它。谁能帮我解决这个错误。

添加查询

    db.collection1.aggregate([ { '$match': {} }, { '$lookup': { from: 'collection2', localField: 'pfId', foreignField: 'pfId', as: 'pt' } }, { '$unwind': '$pt' }, { '$match': {} }, { '$lookup': { from: 'collection3', localField: 'pt.ptId', foreignField: 'ptId', as: 'pd' } }, { '$unwind': '$pd' }, { '$match': {} }, { '$lookup': { from: 'collection4', localField: 'pd.pdId', foreignField: 'pdId', as: 'dl' } }, { '$unwind': '$dl' }, { '$match': { 'dl.currentdl': { '$ne': 'OBSOLETE' }, '$or': [ { 'pd.pdName': { '$regex': /^.*world.*/i } }, { 'dl.r.dF': { '$regex': /^.*world.*/i } }, { 'dl.dlType': { '$regex': /^.*world.*/i } }, { 'dl.dlId': 'WORLD' }, { 'dl.logUserId': 'WORLD' } ] } }, { '$project': {//some_fields} }, { '$group': { _id: null, count: { '$sum': 1 }, results: { '$push': '$$ROOT' } } }, { '$project': { count: 1, results: { '$slice': [ '$results',
0, 10 ] } } }], { allowDiskUse: true })

我必须对数据进行分页,同时检索获取的数据计数。

【问题讨论】:

  • 是的,内存限制在那里,我们可以使用allowDiskUse,但现在从mongo 4.0.14开始,它给出了上述错误,与allowDiskUse无关
  • 您可能希望发布有关查询、集合和索引的其他详细信息

标签: mongodb configuration


【解决方案1】:

所以,经过这么多的努力,这就是我为解决我的问题所做的事情。 首先要理解的是,我不能在不限制数据的情况下将数据推送到数组中。所以我在对管道中的数据进行分组之前使用了$limit$skip。(这也维护了我的查询的分页)。但问题是要保持记录的总数,因为它在分组之前由于限制而丢失。 所以,我想出的解决方案是使用$facet,这有助于我在同一个聚合管道中实现两个管道。

db.prdfam.aggregate([{
$facet: {
"counts":[
{ '$match': {} },
{ '$lookup': { from: 'pt', localField: 'pfId', foreignField: 'pfId', as: 'pt' } },
{ '$unwind': '$pt' }, { '$match': {} }, 
{ '$lookup': { from: 'prds', localField: 'pt.ptId', foreignField: 'ptId', as: 'prd' } },
{ '$unwind': '$prd' }, { '$match': {} }, 
{ '$lookup': { from: 'del', localField: 'prd.prdId', foreignField: 'prdId', as: 'delivery' } }, 
{ '$unwind': '$delivery' }, { '$match': { 'delivery.currentDelivery': { '$ne': 'OBSOLETE' }, 
'$or': [ { 'prd.prdName': { '$regex': /^.*world.*/i } },
{ 'delivery.rInfo.dataFormat': { '$regex': /^.*world.*/i } },
{ 'delivery.dType': { '$regex': /^.*world.*/i } }, 
{ 'delivery.dId': 'WORLD' }, { 'delivery.UserId': 'WORLD' } ] } }, 
{ '$group': { _id: null, count: { '$sum': 1 } } }
],
"results":[
//same lookup & match conditions as in above element 
{ '$project': { //fields to project } }, 
{ '$sort': { updatedAt: -1 } }, {$skip: 0},{ $limit : 10 },
{ '$group': { _id: null, results: { '$push': '$$ROOT' } } },
{ '$project': { results: 1 } }
]
}
}], 
{ allowDiskUse: true })

希望这对其他人有所帮助。干杯:)

【讨论】:

  • 即使使用 allowDiskUse:true,我也会收到相同的错误消息,您还有其他解决方案吗@Ruchika Sharma?
  • @jguilhermeam 是的,allowDiskUse 从 4.0.14 mongo 版本开始不起作用。最好的办法是优化查询以减少查询的输出。就我而言,我必须将我的聚合管道分成两部分,为此我使用了 $facet。
  • 是的,我在 $push 中推送了两个命名字段,然后我只更改了一个字符串。有效。谢谢
  • @RuchikaSharma 你能在这里看看我的问题吗:stackoverflow.com/questions/69127323/… 我在我的情况下应用了 $facet 但不起作用。可能是我对语法的一些错误吗? ——
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2023-03-31
  • 2017-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多