mongoose allowDiskUse (true) нерабочие узлы

#node.js #mongodb #mongoose

#node.js #mongodb #mongoose

Вопрос:

Итак, у меня есть следующий код:

 pastlocation.aggregate([
        {
          '$project': {
            'location': 1, 
            'month': {
              '$month': '$timestamp'
            }
          }
        }, {
          '$match': {
            'month': 11
          }
        },{
          '$group': {
            '_id': '$location.coordinates', 
            'count': {
              '$sum': 1
            }
          }
        }, {
          '$project': {
            '_id': 0, 
            'count': 1, 
            'location.coordinates': {
              '$map': {
                'input': '$_id', 
                'in': {
                  '$toString': '$this'
                }
              }
            }
          }
        },{$sort:{count:-1}}
      ]).allowDiskUse(true).exec(function(err,result) {

        if(err){console.log(err)}
     
      console.log(result)
      res.json(result);
      
  });
 

Из всего, что я прочитал, это правильный способ сделать allowDiskUse при использовании Mongoose с версией 5.11.8

https://mongoosejs.com/docs/api.html#aggregate_Aggregate-allowDiskUse

Однако я, кажется, получаю это сообщение об ошибке.

 MongoError: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.
    at MessageStream.messageHandler (/home/russellharrower/Documents/NodeApps/AdStichr-Server/node_modules/mongodb/lib/cmap/connection.js:268:20)
    at MessageStream.emit (events.js:315:20)
    at processIncomingData (/home/russellharrower/Documents/NodeApps/AdStichr-Server/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
    at MessageStream._write (/home/russellharrower/Documents/NodeApps/AdStichr-Server/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
    at doWrite (_stream_writable.js:403:12)
    at writeOrBuffer (_stream_writable.js:387:5)
    at MessageStream.Writable.write (_stream_writable.js:318:11)
    at TLSSocket.ondata (_stream_readable.js:716:22)
    at TLSSocket.emit (events.js:315:20)
    at addChunk (_stream_readable.js:295:12)
    at readableAddChunk (_stream_readable.js:271:9)
    at TLSSocket.Readable.push (_stream_readable.js:212:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:186:23) {
  operationTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1609147254 },
  ok: 0,
  code: 16819,
  codeName: 'Location16819',
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1609147254 },
    signature: { hash: [Binary], keyId: [Long] }
  }
}
 

Я использую MongoDB Atlas — есть ли настройка, которую мне нужно включить, или я что-то пропустил?

Комментарии:

1. Кажется, что это работает, но проблема на этапах конвейера зависит от индексов и размера данных. Я предлагаю проверить индексы в полях, которые вы сопоставляете и сортируете, и попытаться сократить конвейеры. вы можете использовать match напрямую и удалить первый конвейер проекции, если сможете.

2. @MohamedKamel спасибо за ваш комментарий — вы имеете в виду поместить часть даты в основной проект и удалить верхнюю. проблема в том, что в этой коллекции более 600 000 документов.

Ответ №1:

Проверьте размер буфера сортировки:

 db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
 

(По умолчанию для mongod — 32 МБ, но, похоже, для ATLAS — 100 МБ)
Вы можете попробовать увеличить его, например, до 300 МБ :

 db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: 314572800})
 

также не уверен в вашей схеме, но, возможно, этап $match можно было бы переместить перед $project и $project, чтобы разрешить только location.coordinates для приведенного выше случая…