Итак, я запускаю сервер Node.js с мангустом и пытаюсь выполнить загрузить большой файл с помощью пакета узла GridFS, но получаю следующую ошибку:
MongoServerError: Executor error during find command :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.
Вот код, который я использовал для загрузки файла:
// Stream a single file.
router.get('/stream/:filename', async function(req, res, next){
try{
const file = gfs.find({
filename: req.params.filename
}).toArray((err, files) => {
if (!files || files.length === 0) {
return res.status(404)
.json({
err: "no files exist"
});
}
gfs.openDownloadStreamByName(req.params.filename)
.pipe(res);
});
}catch(err){
return res.status(400).json({
err:'Could not fetch the file.'
})
}
});
Учитывая, что можно ответить на свой вопрос в StackOverflow, я хотел бы задокументировать эту проблему, чтобы мое решение могло помочь другим, столкнувшимся с ней позже.
Оказывается, когда вы загружаете файл в потоковом режиме с помощью GridFS, документы, составляющие файл, сортируются. Согласно этот пост в блоге, при выполнении сортировки MongoDB сначала пытается получить документы, используя порядок, указанный в индексе.. Когда индекс недоступен, он попытается загрузить документы в память и отсортировать их там.
Загвоздка в том, что Mongo по умолчанию настроен на прерывание операции при превышении использования 32 МБ. Вот почему мы сталкиваемся с ошибкой «Сортировка превышена предела памяти», описанной выше. Чтобы решить эту проблему, вам нужно будет создать индекс для поля «n», который содержит порядок фрагментов файла., который вы хотите загрузить. Для этого вы можете либо создать индекс непосредственно через интерфейс вашей базы данных (я использую графический интерфейс MongoDB Compass), либо вы можете создать его с помощью кода, используя метод создатьиндекс():
// Create an index for the 'n' field to help sort the chunks collection.
db.collection('files.chunks').createIndex({n: 1});