Actualicé Mongoose a la última versión (6.0.1) y ahora recibo este error cada vez que se ejecuta .findOne() :
MongooseError: Query was already executed: Streams.findOne({ i: 6 }) at model.Query._wrappedThunk [as _findOne] (C:\Users\honza\ZiggerTestMaster\node_modules\mongoose\lib\helpers\query\wrapThunk.js:21:19) at C:\Users\honza\ZiggerTestMaster\node_modules\kareem\index.js:370:33 at processTicksAndRejections (node:internal/process/task_queues:78:11) at runNextTicks (node:internal/process/task_queues:65:3) at listOnTimeout (node:internal/timers:526:9) at processTimers (node:internal/timers:500:7) { originalStack: 'Error\n' + ' at model.Query._wrappedThunk [as _findOne] (C:\\Users\\honza\\ZiggerTestMaster\\node_modules\\mongoose\\lib\\helpers\\query\\wrapThunk.js:25:28)\n' + ' at C:\\Users\\honza\\ZiggerTestMaster\\node_modules\\kareem\\index.js:370:33\n' + ' at processTicksAndRejections (node:internal/process/task_queues:78:11)\n' + ' at runNextTicks (node:internal/process/task_queues:65:3)\n' + ' at listOnTimeout (node:internal/timers:526:9)\n' + ' at processTimers (node:internal/timers:500:7)' }Mi código es el siguiente:
var visitorData = Visitor.find({}); app.get("/retrieve", function(req,res){ visitorData.exec(function (err,data) { if (err) { throw err; } res.render("retrieve", { title:"View Visitor Data", records: data}); }); });Se ejecuta correctamente la primera vez que abro la ruta pero, cada vez que la actualizo, arroja el error anterior. Ha estado sucediendo desde que Mongoose obtuvo la última versión.
El error surge predominantemente porque la misma consulta se ejecuta más de una vez, la causa más frecuente es que, sin saberlo, se usa la promesa y la devolución de llamada al mismo tiempo, para evitar tales errores, se genera este error. Para deshacerse de este error, cumpla con la promesa o la devolución de llamada al ejecutar este método de consulta.
Utilizar:
await Model.findOneAndUpdate(query,doc,options) // (or) regular .then() .catch() syntax Model.findOneAndUpdate(query) .then(res=>...) .catch(err=>...)(O)
Model.findOneAndUpdate(query, doc, options, callback) El mismo principio se aplica a métodos similares como findByIdAndUpdate .
No use la devolución de llamada dentro de findOne, en su lugar use .then() , después de la consulta, así
Visitor.find({}) .then(function (err, data) { if (!err) { res.render("retrieve", { title: "View Visitor Data", records: data }); } else { throw err; } }Lo más probable es que esto funcione, de lo contrario, use clone() si es necesario, como lo indica Avis
No estoy seguro de los detalles, pero los problemas míos y de mis compañeros de trabajo se solucionaron al degradar mongoose a 5.13.14
Mangosta ya no permite ejecutar el mismo objeto de consulta dos veces. Si lo hace, obtendrá un error de Consulta ya ejecutada. Ejecutar la misma instancia de consulta dos veces suele indicar que se mezclan devoluciones de llamada y promesas, pero si necesita ejecutar la misma consulta dos veces, puede llamar a ".clone();" para clonar la consulta y volver a ejecutarla.
envuelva su consulta dentro de async-await.
const visitorData = async() => { return await Visitor.find({}); }Mongoose v6 no permite consultas duplicadas.
Mangosta ya no permite ejecutar el mismo objeto de consulta dos veces. Si lo hace, obtendrá un error de Consulta ya ejecutada. Ejecutar la misma instancia de consulta dos veces suele indicar que se mezclan devoluciones de llamada y promesas, pero si necesita ejecutar la misma consulta dos veces, puede llamar a Query#clone() para clonar la consulta y volver a ejecutarla. Ver gh-7398
Ejecución de consultas duplicadas
En mi caso, asumí que mi resolución de Apollo Server esperará a que la promesa se resuelva y devuelva el resultado, pero ese no fue el caso. Así que tuve que agregar async/await a la consulta de mongoose.
Tuve los mismos problemas, pero las notas de la versión sobre mongoose ayudaron, .clone() al método .find() :
https://mongoosejs.com/docs/migrating_to_6.html#duplicate-query-execution
Mangosta ya no permite ejecutar el mismo objeto de consulta dos veces. Si lo hace, obtendrá un error de Consulta ya ejecutada. Ejecutar la misma instancia de consulta dos veces suele indicar que se mezclan devoluciones de llamada y promesas, pero si necesita ejecutar la misma consulta dos veces, puede llamar a Query#clone() para clonar la consulta y volver a ejecutarla.
Entonces, todo lo que necesita hacer es agregar un método .clone() al final del método mongoose que debe llamarse simultáneamente como se muestra a continuación (reestructuré un poco su código):
app.get("/retrieve", function (req, res) { Visitor.find({}, function (err, data) { if (!err) { res.render("retrieve", { title: "View Visitor Data", records: data }); } else { throw err; } }).clone().catch(function(err){ console.log(err)}) });