Skip to content

Commit 266804b

Browse files
committed
fix: handle casting $or within $elemMatch
Fix #13974
1 parent 4d084e9 commit 266804b

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/schema/array.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,8 @@ function cast$elemMatch(val, context) {
623623
discriminators[val[discriminatorKey]] != null) {
624624
return cast(discriminators[val[discriminatorKey]], val, null, this && this.$$context);
625625
}
626-
627-
return cast(this.casterConstructor.schema, val, null, this && this.$$context);
626+
const schema = this.casterConstructor.schema ?? context.schema;
627+
return cast(schema, val, null, this && this.$$context);
628628
}
629629

630630
const handle = SchemaArray.prototype.$conditionalHandlers = {};

test/model.query.casting.test.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ describe('model query casting', function() {
754754
assert.strictEqual(doc.outerArray[0].innerArray[0], 'onetwothree');
755755
});
756756
});
757-
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() {
757+
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() {
758758
const testSchema = new Schema({
759759
arr: [[String]]
760760
});
@@ -766,6 +766,31 @@ describe('model query casting', function() {
766766
assert(res);
767767
assert(res[0].arr);
768768
});
769+
it('should not throw a cast error when dealing with an array of objects in combination with $elemMatch (gh-13974)', async function() {
770+
const testSchema = new Schema({
771+
arr: [Object]
772+
});
773+
774+
const Test = db.model('Test', testSchema);
775+
const obj1 = new Test({ arr: [{ id: 'one' }, { id: 'two' }] });
776+
await obj1.save();
777+
778+
const obj2 = new Test({ arr: [{ id: 'two' }, { id: 'three' }] });
779+
await obj2.save();
780+
781+
const obj3 = new Test({ arr: [{ id: 'three' }, { id: 'four' }] });
782+
await obj3.save();
783+
784+
const res = await Test.find({
785+
arr: {
786+
$elemMatch: {
787+
$or: [{ id: 'one' }, { id: 'two' }]
788+
}
789+
}
790+
}).sort({ _id: 1 });
791+
assert.ok(res);
792+
assert.deepStrictEqual(res.map(doc => doc.arr[1].id), ['two', 'three']);
793+
});
769794
});
770795

771796
function _geojsonPoint(coordinates) {

0 commit comments

Comments
 (0)