Skip to content

Commit 1ec00bb

Browse files
authored
Merge pull request #14171 from tosaka-n/featos/fix_cast_and_elemmatch
fix: cast error when there is an elemMatch in the and clause
2 parents 9c17773 + b052e65 commit 1ec00bb

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

lib/schema/array.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,14 +638,14 @@ handle.$and = createLogicalQueryOperatorHandler('$and');
638638
handle.$nor = createLogicalQueryOperatorHandler('$nor');
639639

640640
function createLogicalQueryOperatorHandler(op) {
641-
return function logicalQueryOperatorHandler(val) {
641+
return function logicalQueryOperatorHandler(val, context) {
642642
if (!Array.isArray(val)) {
643643
throw new TypeError('conditional ' + op + ' requires an array');
644644
}
645645

646646
const ret = [];
647647
for (const obj of val) {
648-
ret.push(cast(this.casterConstructor.schema, obj, null, this && this.$$context));
648+
ret.push(cast(this.casterConstructor.schema ?? context.schema, obj, null, this && this.$$context));
649649
}
650650

651651
return ret;

test/model.query.casting.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,38 @@ describe('model query casting', function() {
791791
assert.ok(res);
792792
assert.deepStrictEqual(res.map(doc => doc.arr[1].id), ['two', 'three']);
793793
});
794+
795+
it('should not throw a cast error when dealing with an array of objects in combination with $elemMatch and nested $and', async function() {
796+
const testSchema = new Schema({
797+
arr: [Object]
798+
});
799+
800+
const Test = db.model('Test', testSchema);
801+
const obj1 = new Test({ arr: [{ id: 'one', name: 'sample1' }, { id: 'two' }] });
802+
await obj1.save();
803+
804+
const obj2 = new Test({ arr: [{ id: 'two', name: 'sample1' }, { id: 'three' }] });
805+
await obj2.save();
806+
807+
const obj3 = new Test({ arr: [{ id: 'three', name: 'sample1' }, { id: 'four' }] });
808+
await obj3.save();
809+
const res = await Test.find({
810+
arr: {
811+
$elemMatch: {
812+
$and: [
813+
{ name: 'sample1' },
814+
{ $or: [
815+
{ id: 'one' },
816+
{ id: 'two' }
817+
] }
818+
]
819+
}
820+
}
821+
}).sort({ _id: 1 });
822+
assert.ok(res);
823+
assert.equal(res.length, 2);
824+
assert.deepStrictEqual(res.map(doc => doc.arr[1].id), ['two', 'three']);
825+
});
794826
});
795827

796828
function _geojsonPoint(coordinates) {

0 commit comments

Comments
 (0)