#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 для приведенного выше случая…