Estoy tratando de cargar entradas de mi base de datos mongoDB una a la vez. Funciona para aproximadamente 400/1000 entradas y luego se rompe con el siguiente error:
Executor error during find command :: caused by :: Sort exceeded memory limit of 33554432 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in.
Mi solicitud de obtención de Axios se ve así:
for (let i = 0; i < total; i++) { await axios({ method: "GET", url: "/api/entries/", params: { from: index + i, _limit: 1 }, }) .then((res) => { setPics((prev) => { return [...new Set([...prev, ...res.data])]; }); setIndex((prev) => prev++) setMoreEntries(res.data.length > 0) }) }y en mi controlador, mi función GET se ve así:
const getEntries = asyncHandler(async (req, res) => { const entries = await Entry.find().allowDiskUse(true).sort({ createdAt: 'desc' }).skip(req.query.from).limit(req.query._limit) res.status(200).json(entries) }) Todo funciona perfectamente hasta que se han cargado aproximadamente la mitad de las entradas, luego se rompe. Pensé que agregar allowDiskUse(true) lo solucionaría, pero el mismo resultado.
Editar: debo mencionar que si .sort({ createdAt: 'desc' }) funciona perfectamente, pero se carga en el orden opuesto.
La sintaxis en sí está bien, no estoy muy seguro de por qué no funciona para usted.
Tengo dos teorías que podrían ser posibles:
Los clústeres gratuitos Atlas M0 y los clústeres compartidos M2/M5 no son compatibles con allowDiskUse
Independientemente de la fuente del problema, le recomiendo que lo resuelva de la siguiente manera:
Cree un índice en createdAt , ordenar cuando existe un índice no escanea los documentos en la memoria, lo que hará que la consulta sea más eficiente y resolverá este problema.
Simplemente use el índice _id y ordene con { _id: -1} , de su comentario sobre eliminar la operación de ordenación y obtener documentos en orden inverso, parece que su createdAt corresponde a la fecha de creación del documento (tiene sentido), el ObjectId _id está aumentando monótonamente lo que significa que puede usar ese campo para ordenar.
Terminé simplemente haciendo un bucle for hacia atrás y usando skip en lugar de ordenar, como
const getOne = asyncHandler(async (req, res) => { const entry = await Entry.findOne({}, {}).allowDiskUse(true).skip(req.query.from) res.status(200).json(entry) })Lo cual funcionó perfectamente para mí, pero la respuesta de Tom es lo que estaba buscando, gracias :)