Skip to content

Commit

Permalink
fix: handle casting $or within $elemMatch
Browse files Browse the repository at this point in the history
Fix #13974
  • Loading branch information
vkarpov15 committed Oct 26, 2023
1 parent 4d084e9 commit 266804b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/schema/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,8 @@ function cast$elemMatch(val, context) {
discriminators[val[discriminatorKey]] != null) {
return cast(discriminators[val[discriminatorKey]], val, null, this && this.$$context);
}

return cast(this.casterConstructor.schema, val, null, this && this.$$context);
const schema = this.casterConstructor.schema ?? context.schema;
return cast(schema, val, null, this && this.$$context);
}

const handle = SchemaArray.prototype.$conditionalHandlers = {};
Expand Down
27 changes: 26 additions & 1 deletion test/model.query.casting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ describe('model query casting', function() {
assert.strictEqual(doc.outerArray[0].innerArray[0], 'onetwothree');
});
});
it('should not throw a cast error when dealing with an array of an array of strings in combination with $elemMach and $not (gh-13880)', async function() {
it('should not throw a cast error when dealing with an array of an array of strings in combination with $elemMatch and $not (gh-13880)', async function() {
const testSchema = new Schema({
arr: [[String]]
});
Expand All @@ -766,6 +766,31 @@ describe('model query casting', function() {
assert(res);
assert(res[0].arr);
});
it('should not throw a cast error when dealing with an array of objects in combination with $elemMatch (gh-13974)', async function() {
const testSchema = new Schema({
arr: [Object]
});

const Test = db.model('Test', testSchema);
const obj1 = new Test({ arr: [{ id: 'one' }, { id: 'two' }] });
await obj1.save();

const obj2 = new Test({ arr: [{ id: 'two' }, { id: 'three' }] });
await obj2.save();

const obj3 = new Test({ arr: [{ id: 'three' }, { id: 'four' }] });
await obj3.save();

const res = await Test.find({
arr: {
$elemMatch: {
$or: [{ id: 'one' }, { id: 'two' }]
}
}
}).sort({ _id: 1 });
assert.ok(res);
assert.deepStrictEqual(res.map(doc => doc.arr[1].id), ['two', 'three']);
});
});

function _geojsonPoint(coordinates) {
Expand Down

0 comments on commit 266804b

Please sign in to comment.