Reputation: 6788
From my mongo shell I can run functions with db.eval
like:
db.eval('return 7;');
And, but for a deprecation warning, the parameter function is run properly.
Now I want to call such a 'script' from node.js
, through mongoose
.
I've tried to just call db.eval
with the stringified function code as parameter (as in here):
mongoose.connect(PATH_TO_A_MONGO_DATABASE);
mongoose.connection.db.eval('return 9;', function(err, result){
console.log(result);
//etc.
});
This silently ignores the callback. No error is thrown, and the callback function is never called.
When doing this, I checked that mongoose.connection.db.eval
is actually a function.
Since db.eval
also has a Promise interface, also tried:
mongoose.connection.db.eval('return 5;').then(console.log).catch(console.log);
With the same result: no errors, just silence.
So, I guess I'm missing something with the syntax, but I can't find documentation or examples about this. Any similar questions like this or this didn't help.
PD1: I'm willing to do this because I need to call a procedure stored in system.js
through mongoose
. I can't do that too. However, I can't even run a silly script like return 5;
, so I'm asking for the simpler task before. Any advice on how to call server scripts with mongoose is welcome.
PD2: I'm aware stored server scripts in mongo are a bad practice, and that they are deprecated for a reason and so on... but I can't just decide about that. I've been told to do that at my company, and the co-worker who set up the original code of the stored server script is not here now.
Upvotes: 0
Views: 1792
Reputation: 6788
Ok, I figured out why my db.eval
callbacks was being ignored. It is related with the mongoose connection.
If you start a connection like:
const conn = mongoose.connect(PATH_TO_DB);
And then just make a query:
conn.model(a_collection, a_schema).find({}).exec().then()...
Even if you just call the query right after the connection -it is, logically, an asynchronous process-, mongooose figures that it has to wait to the connection to be in a proper state, then fire the query, then call the callback with the query results.
However, this doesn't work the same way with db.eval()
. just trying to call db.eval()
right after the call to the connection, the callback is silently ignored:
const conn = mongoose.connect(PATH_TO_DB);
conn.db.eval('return 5;', (err, response) => {
//nothing happends
})
That was the way I was creating the connection and calling db.eval
, so I couldn't get db.eval()
to work.
In order to fire a db.eval
and make it work, it seems that you need to wait for the connection explicitly:
const conn = mongoose.connect(PATH_TO_DB, err => {
mongoose.connection.db.eval('return 5', (err, result) => {
result; //5!
})
});
To make a query before any attemps to call db.eval
also works:
const conn = mongoose.connect(PATH_TO_DB);
conn.model(a_collection, a_schema).find({}).exec()
.then(() => {
conn.db.eval('return 5', (err, result) => {
result; //5!
})
})
Upvotes: 1