New Issue Checklist
Current Behavior
When using Parse.Query.aggregate() with a $match stage, JavaScript Date objects used as comparison values (e.g. $lte, $gte) are not converted to BSON dates when the field is referenced by its internal MongoDB name (e.g. _created_at). The same comparison works correctly when using the Parse-style field name (e.g. createdAt).
This causes date comparisons on _created_at or _updated_at to silently return zero results, even though matching documents exist.
Reproduction
// Create some objects
const obj = new Parse.Object('TestClass');
await obj.save();
// Wait so the object is older than 1 second
await new Promise(r => setTimeout(r, 2000));
const date = new Date(Date.now() - 1000);
const query = new Parse.Query('TestClass');
// ❌ Using internal field name — returns [] (no results)
const result1 = await query.aggregate([
{ $match: { _created_at: { $lte: date } } },
{ $count: 'total' },
]);
Expected Behavior
The issue is that doing these transformations may cause a breaking change because parse-server is iteratively going through the whole pipeline and renames the keys, regardless of whether they are root-level keys or nested keys, which have nothing to do with the Parse schema and the assigned field types.
The proper fix is to phase these transformations out and treat aggregation query as a raw pipeline. This will require new per-query and parse-server options and a controlled breaking change.
Workaround
Use Parse-style field names (createdAt, updatedAt) instead of internal names (_created_at, _updated_at) in $match stages when comparing against JS Date values. Alternatively, use MongoDB expressions ($expr with $$NOW, $dateSubtract, etc.) which bypass the adapter's value transformation entirely.
Environment
- Parse Server version:
9.8.0-alpha.12
New Issue Checklist
Current Behavior
When using
Parse.Query.aggregate()with a$matchstage, JavaScriptDateobjects used as comparison values (e.g.$lte,$gte) are not converted to BSON dates when the field is referenced by its internal MongoDB name (e.g._created_at). The same comparison works correctly when using the Parse-style field name (e.g.createdAt).This causes date comparisons on
_created_ator_updated_atto silently return zero results, even though matching documents exist.Reproduction
Expected Behavior
The issue is that doing these transformations may cause a breaking change because parse-server is iteratively going through the whole pipeline and renames the keys, regardless of whether they are root-level keys or nested keys, which have nothing to do with the Parse schema and the assigned field types.
The proper fix is to phase these transformations out and treat aggregation query as a raw pipeline. This will require new per-query and parse-server options and a controlled breaking change.
Workaround
Use Parse-style field names (
createdAt,updatedAt) instead of internal names (_created_at,_updated_at) in$matchstages when comparing against JSDatevalues. Alternatively, use MongoDB expressions ($exprwith$$NOW,$dateSubtract, etc.) which bypass the adapter's value transformation entirely.Environment
9.8.0-alpha.12