Mongoose 4.7.9
Just started having this Error on code that has been working for months:
Error: Can't use $exists with Array. at SchemaArray.castForQuery (/app/node_modules/mongoose/lib/schema/array.js:210:13)
Could it be related to #4933 ?
Confirmed rolling back to 4.7.8 works.
Just checked mongoose schemas and this error is indeed related to #4933. Those schema types that inherit defaults $conditionalHandlers
work since they will also have the $exists
handler that is now part of schametype.js.
The string
schema for example is OK:
SchemaString.prototype.$conditionalHandlers =
utils.options(SchemaType.prototype.$conditionalHandlers, {
$all: handleArray,
$gt: handleSingle,
$gte: handleSingle,
$lt: handleSingle,
$lte: handleSingle,
$options: handleSingle,
$regex: handleSingle,
$not: handleSingle
});
However, array
doesn't do the same:
var handle = SchemaArray.prototype.$conditionalHandlers = {};
handle.$all = cast$all;
handle.$options = String;
handle.$elemMatch = cast$elemMatch;
// and so on
Now this can also affects LOT of plugins, I actually ended up here because a working code with mongoose-moment started failing without any change.
@vkarpov15 , as explained, I think this is a potential breaking change for lot of plugins, not just a patch bump version. What if it is rolled back and applied for the next major version?
Thanks for opening an issue, I've created a simple repro script here:
const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
// Constants
const GITHUB_ISSUE = `gh-4937`;
exec();
function exec() {
connectToDb()
.then(() => co(function*(){
const schema = new mongoose.Schema({
name: String,
petElephants: [String]
});
const Model = mongoose.model('Model', schema);
const doc = yield Model.create({
name: 'Elephant Master',
petElephants: ['Dumbo']
});
const foundDoc = yield Model.find({
petElephants: { $exists: true }
});
assert.ok(true);
}))
.catch(error => {
console.error(error);
process.exit(2);
})
}
function connectToDb() {
return co(function*() {
mongoose.connect(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
})
}
Hi @gastonelhordoy sorry about this, this is definitely a bug and due to some minor refactoring that went wrong. Will push 4.8.1 with a fix tomorrow.
Hey @vkarpov15 np, thanks for the quick fix. BTW, this change will remain in the 4.7.x version? What about plugins with schema types that do not extends the default $conditionalHandler
hash?
@gastonelhordoy yeah for now the change will stay in 4.7.x since 4.8.x is already out, I'd rather not release another 4.7.
If your type extends from the mongoose SchemaType
you should be fine. The problem was that the Array type overwrote the built-in $conditionalHandler
hash and so didn't include a $exists
handler. If you don't do that you should be fine, feel free to let me know in this thread if you have any more problems :+1:
Ya the plugin I was using was doing the same thing, I already fixed it.
However, I feel like if other plugins do the same this change can have an impact on production apps requiring [email protected] (not yet 4.8), like in my case.
Anyways... thanks for the great work!
I suppose the other alternative is to deprecate 4.7.9 in npm to avoid this side effect. Do you think that's worth doing?