Skip to content

Commit d0d30c4

Browse files
authored
feat: Remove deprecation DEPPS1: Native MongoDB syntax in aggregation pipeline (parse-community#8362)
BREAKING CHANGE: The MongoDB aggregation pipeline requires native MongoDB syntax instead of the custom Parse Server syntax; for example pipeline stage names require a leading dollar sign like `$match` and the MongoDB document ID is referenced using `_id` instead of `objectId` (parse-community#8362)
1 parent df00cbe commit d0d30c4

8 files changed

+149
-148
lines changed

Diff for: DEPRECATIONS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
44

55
| ID | Change | Issue | Deprecation [ℹ️][i_deprecation] | Planned Removal [ℹ️][i_removal] | Status [ℹ️][i_status] | Notes |
66
|--------|-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------|
7-
| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - |
7+
| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
88
| DEPPS2 | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
99
| DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |
1010
| DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |

Diff for: spec/AggregateRouter.spec.js

+42-32
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
11
const AggregateRouter = require('../lib/Routers/AggregateRouter').AggregateRouter;
22

33
describe('AggregateRouter', () => {
4-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
54
it('get pipeline from Array', () => {
65
const body = [
76
{
8-
group: { objectId: {} },
7+
$group: { _id: {} },
98
},
109
];
1110
const expected = [{ $group: { _id: {} } }];
1211
const result = AggregateRouter.getPipeline(body);
1312
expect(result).toEqual(expected);
1413
});
1514

16-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
1715
it('get pipeline from Object', () => {
1816
const body = {
19-
group: { objectId: {} },
17+
$group: { _id: {} },
2018
};
2119
const expected = [{ $group: { _id: {} } }];
2220
const result = AggregateRouter.getPipeline(body);
2321
expect(result).toEqual(expected);
2422
});
2523

26-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
2724
it('get pipeline from Pipeline Operator (Array)', () => {
2825
const body = {
2926
pipeline: [
3027
{
31-
group: { objectId: {} },
28+
$group: { _id: {} },
3229
},
3330
],
3431
};
@@ -37,55 +34,53 @@ describe('AggregateRouter', () => {
3734
expect(result).toEqual(expected);
3835
});
3936

40-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
4137
it('get pipeline from Pipeline Operator (Object)', () => {
4238
const body = {
4339
pipeline: {
44-
group: { objectId: {} },
40+
$group: { _id: {} },
4541
},
4642
};
4743
const expected = [{ $group: { _id: {} } }];
4844
const result = AggregateRouter.getPipeline(body);
4945
expect(result).toEqual(expected);
5046
});
5147

52-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
5348
it('get pipeline fails multiple keys in Array stage ', () => {
5449
const body = [
5550
{
56-
group: { objectId: {} },
57-
match: { name: 'Test' },
51+
$group: { _id: {} },
52+
$match: { name: 'Test' },
5853
},
5954
];
60-
try {
61-
AggregateRouter.getPipeline(body);
62-
} catch (e) {
63-
expect(e.message).toBe('Pipeline stages should only have one key found group, match');
64-
}
55+
expect(() => AggregateRouter.getPipeline(body)).toThrow(
56+
new Parse.Error(
57+
Parse.Error.INVALID_QUERY,
58+
'Pipeline stages should only have one key but found $group, $match.'
59+
)
60+
);
6561
});
6662

67-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
6863
it('get pipeline fails multiple keys in Pipeline Operator Array stage ', () => {
6964
const body = {
7065
pipeline: [
7166
{
72-
group: { objectId: {} },
73-
match: { name: 'Test' },
67+
$group: { _id: {} },
68+
$match: { name: 'Test' },
7469
},
7570
],
7671
};
77-
try {
78-
AggregateRouter.getPipeline(body);
79-
} catch (e) {
80-
expect(e.message).toBe('Pipeline stages should only have one key found group, match');
81-
}
72+
expect(() => AggregateRouter.getPipeline(body)).toThrow(
73+
new Parse.Error(
74+
Parse.Error.INVALID_QUERY,
75+
'Pipeline stages should only have one key but found $group, $match.'
76+
)
77+
);
8278
});
8379

84-
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
8580
it('get search pipeline from Pipeline Operator (Array)', () => {
8681
const body = {
8782
pipeline: {
88-
search: {},
83+
$search: {},
8984
},
9085
};
9186
const expected = [{ $search: {} }];
@@ -105,7 +100,7 @@ describe('AggregateRouter', () => {
105100
it('support nested stage names starting with `$`', () => {
106101
const body = [
107102
{
108-
lookup: {
103+
$lookup: {
109104
from: 'ACollection',
110105
let: { id: '_id' },
111106
as: 'results',
@@ -145,11 +140,11 @@ describe('AggregateRouter', () => {
145140

146141
it('support the use of `_id` in stages', () => {
147142
const body = [
148-
{ match: { _id: 'randomId' } },
149-
{ sort: { _id: -1 } },
150-
{ addFields: { _id: 1 } },
151-
{ group: { _id: {} } },
152-
{ project: { _id: 0 } },
143+
{ $match: { _id: 'randomId' } },
144+
{ $sort: { _id: -1 } },
145+
{ $addFields: { _id: 1 } },
146+
{ $group: { _id: {} } },
147+
{ $project: { _id: 0 } },
153148
];
154149
const expected = [
155150
{ $match: { _id: 'randomId' } },
@@ -161,4 +156,19 @@ describe('AggregateRouter', () => {
161156
const result = AggregateRouter.getPipeline(body);
162157
expect(result).toEqual(expected);
163158
});
159+
160+
it('should throw with invalid stage', () => {
161+
expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow(
162+
new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`)
163+
);
164+
});
165+
166+
it('should throw with invalid group', () => {
167+
expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow(
168+
new Parse.Error(
169+
Parse.Error.INVALID_QUERY,
170+
`Cannot use 'objectId' in aggregation stage $group.`
171+
)
172+
);
173+
});
164174
});

Diff for: spec/CloudCode.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2774,7 +2774,7 @@ describe('afterFind hooks', () => {
27742774
const obj = new Parse.Object('MyObject');
27752775
const pipeline = [
27762776
{
2777-
group: { objectId: {} },
2777+
$group: { _id: {} },
27782778
},
27792779
];
27802780
obj

0 commit comments

Comments
 (0)