fix: Parse.Query.containedIn and matchesQuery do not work with nested objects (#9738)
This commit is contained in:
@@ -5306,4 +5306,72 @@ describe('Parse.Query testing', () => {
|
|||||||
expect(score).toEqual([1]);
|
expect(score).toEqual([1]);
|
||||||
}, { useMasterKey: true });
|
}, { useMasterKey: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe_only_db('mongo')('query nested keys', () => {
|
||||||
|
it('queries nested key using equalTo', async () => {
|
||||||
|
const child = new Parse.Object('Child');
|
||||||
|
child.set('key', 'value');
|
||||||
|
await child.save();
|
||||||
|
|
||||||
|
const parent = new Parse.Object('Parent');
|
||||||
|
parent.set('some', {
|
||||||
|
nested: {
|
||||||
|
key: {
|
||||||
|
child,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await parent.save();
|
||||||
|
|
||||||
|
const query1 = await new Parse.Query('Parent')
|
||||||
|
.equalTo('some.nested.key.child', child)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
expect(query1.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('queries nested key using containedIn', async () => {
|
||||||
|
const child = new Parse.Object('Child');
|
||||||
|
child.set('key', 'value');
|
||||||
|
await child.save();
|
||||||
|
|
||||||
|
const parent = new Parse.Object('Parent');
|
||||||
|
parent.set('some', {
|
||||||
|
nested: {
|
||||||
|
key: {
|
||||||
|
child,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await parent.save();
|
||||||
|
|
||||||
|
const query1 = await new Parse.Query('Parent')
|
||||||
|
.containedIn('some.nested.key.child', [child])
|
||||||
|
.find();
|
||||||
|
|
||||||
|
expect(query1.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('queries nested key using matchesQuery', async () => {
|
||||||
|
const child = new Parse.Object('Child');
|
||||||
|
child.set('key', 'value');
|
||||||
|
await child.save();
|
||||||
|
|
||||||
|
const parent = new Parse.Object('Parent');
|
||||||
|
parent.set('some', {
|
||||||
|
nested: {
|
||||||
|
key: {
|
||||||
|
child,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await parent.save();
|
||||||
|
|
||||||
|
const query1 = await new Parse.Query('Parent')
|
||||||
|
.matchesQuery('some.nested.key.child', new Parse.Query('Child').equalTo('key', 'value'))
|
||||||
|
.find();
|
||||||
|
|
||||||
|
expect(query1.length).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ function transformQueryKeyValue(className, key, value, schema, count = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle query constraints
|
// Handle query constraints
|
||||||
const transformedConstraint = transformConstraint(value, field, count);
|
const transformedConstraint = transformConstraint(value, field, key, count);
|
||||||
if (transformedConstraint !== CannotTransform) {
|
if (transformedConstraint !== CannotTransform) {
|
||||||
if (transformedConstraint.$text) {
|
if (transformedConstraint.$text) {
|
||||||
return { key: '$text', value: transformedConstraint.$text };
|
return { key: '$text', value: transformedConstraint.$text };
|
||||||
@@ -651,12 +651,15 @@ function transformTopLevelAtom(atom, field) {
|
|||||||
// If it is not a valid constraint but it could be a valid something
|
// If it is not a valid constraint but it could be a valid something
|
||||||
// else, return CannotTransform.
|
// else, return CannotTransform.
|
||||||
// inArray is whether this is an array field.
|
// inArray is whether this is an array field.
|
||||||
function transformConstraint(constraint, field, count = false) {
|
function transformConstraint(constraint, field, queryKey, count = false) {
|
||||||
const inArray = field && field.type && field.type === 'Array';
|
const inArray = field && field.type && field.type === 'Array';
|
||||||
|
// Check wether the given key has `.`
|
||||||
|
const isNestedKey = queryKey.indexOf('.') > -1;
|
||||||
if (typeof constraint !== 'object' || !constraint) {
|
if (typeof constraint !== 'object' || !constraint) {
|
||||||
return CannotTransform;
|
return CannotTransform;
|
||||||
}
|
}
|
||||||
const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom;
|
// For inArray or nested key, we need to transform the interior atom
|
||||||
|
const transformFunction = (inArray || isNestedKey) ? transformInteriorAtom : transformTopLevelAtom;
|
||||||
const transformer = atom => {
|
const transformer = atom => {
|
||||||
const result = transformFunction(atom, field);
|
const result = transformFunction(atom, field);
|
||||||
if (result === CannotTransform) {
|
if (result === CannotTransform) {
|
||||||
|
|||||||
Reference in New Issue
Block a user