Closed
Description
Issue Description
When using a Pointer for matches on an aggregation query, the system queries against the queried object's class, not against the Pointer's class
Steps to reproduce
Run an aggregate query against an object with a Pointer reference:
Snapp.region is a 'Region' pbje
e.g.
let mostPopularSnapps = new Parse.Query(Parse.Object.extend('Snapp'))
let region = Parse.Object.extend('Region')
region.id = "CLtNoVCMF8"
const pipeline = [
{ match: { region: "CLtNoVCMF8" } },
{ group: { objectId: '$_p_expertIdentifiedPlant', count: { $sum: 1 } } },
{ sort: { count: -1 } }
]
mostPopularSnapps
.aggregate(pipeline, { useMasterKey: true })
.then(items => {
console.log(items)
})
should match the Mongo pipeline:
[
{ $match: { _p_region: /CLtNoVCMF8$/ }},
{ $group: { _id: "$_p_expertIdentifiedPlant", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]
Expected Results
I expect it to return results matching only that region (by id).
Actual Outcome
It returns 0 results, as the match pipeline is malformed.
Environment Setup
-
Server
- parse-server version (Be specific! Don't say 'latest'.) : [2.7.2]
- Operating System: [MacOS]
- Hardware: [MacBook Pro 13 inch mid-2012]
- Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): [localhost]
-
Database
- MongoDB version: [3.6.2]
- Storage engine: [WiredTiger]
- Hardware: [Same as above]
- Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): [Same as above]
Logs/Trace
None
Potential PR
In MongoStorageAdapter.js:498, the stage.$match function parses the pipeline match like so:
if (stage.$match) {
for (const field in stage.$match) {
if (schema.fields[field] && schema.fields[field].type === 'Pointer') {
const transformMatch = { [`_p_${field}`]: `${className}$${stage.$match[field]}` };
stage.$match = transformMatch;
}
if (field === 'objectId') {
const transformMatch = Object.assign({}, stage.$match);
transformMatch._id = stage.$match[field];
delete transformMatch.objectId;
stage.$match = transformMatch;
}
}
}
It seems to me that this line:
const transformMatch = { [`_p_${field}`]: `${className}$${stage.$match[field]}` };
should be:
const transformMatch = { [`_p_${field}`]: `${schema.fields[field].targetClass}$${stage.$match[field]}` };
Happy to open a PR if this should be correct behaviour? I'm relatively new to Parse, so want to confirm what the outcome should be here.
Metadata
Metadata
Assignees
Labels
No labels