Skip to content

Commit 6aea65c

Browse files
mtrezzadblythy
authored andcommitted
feat: add MongoDB 5.2 support (#7894)
1 parent fff2db5 commit 6aea65c

File tree

3 files changed

+100
-12
lines changed

3 files changed

+100
-12
lines changed

.github/workflows/ci.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,18 @@ jobs:
101101
strategy:
102102
matrix:
103103
include:
104+
- name: MongoDB 5.2, ReplicaSet, WiredTiger
105+
MONGODB_VERSION: 5.2.1
106+
MONGODB_TOPOLOGY: replicaset
107+
MONGODB_STORAGE_ENGINE: wiredTiger
108+
NODE_VERSION: 14.18.1
104109
- name: MongoDB 5.1, ReplicaSet, WiredTiger
105-
MONGODB_VERSION: 5.1.0
110+
MONGODB_VERSION: 5.1.1
106111
MONGODB_TOPOLOGY: replicaset
107112
MONGODB_STORAGE_ENGINE: wiredTiger
108113
NODE_VERSION: 14.18.1
109114
- name: MongoDB 5.0, ReplicaSet, WiredTiger
110-
MONGODB_VERSION: 5.0.3
115+
MONGODB_VERSION: 5.0.6
111116
MONGODB_TOPOLOGY: replicaset
112117
MONGODB_STORAGE_ENGINE: wiredTiger
113118
NODE_VERSION: 16.13.0

README.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,14 @@ Parse Server is continuously tested with the most recent releases of Node.js to
122122
#### MongoDB
123123
Parse Server is continuously tested with the most recent releases of MongoDB to ensure compatibility. We follow the [MongoDB support schedule](https://www.mongodb.com/support-policy) and only test against versions that are officially supported and have not reached their end-of-life date.
124124

125-
| Version | Latest Version | End-of-Life | Compatible |
126-
|-------------|----------------|--------------|------------|
127-
| MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Yes |
128-
| MongoDB 4.2 | 4.2.17 | TBD | ✅ Yes |
129-
| MongoDB 4.4 | 4.4.10 | TBD | ✅ Yes |
130-
| MongoDB 5.0 | 5.0.3 | January 2024 | ✅ Yes |
131-
| MongoDB 5.1 | 5.1.0 | January 2024 | ✅ Yes |
125+
| Version | Latest Version | End-of-Life | Compatible |
126+
|-------------|----------------|-------------|------------|
127+
| MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Yes |
128+
| MongoDB 4.2 | 4.2.17 | TBD | ✅ Yes |
129+
| MongoDB 4.4 | 4.4.10 | TBD | ✅ Yes |
130+
| MongoDB 5.0 | 5.0.6 | TBD | ✅ Yes |
131+
| MongoDB 5.1 | 5.1.1 | TBD | ✅ Yes |
132+
| MongoDB 5.2 | 5.2.1 | TBD | ✅ Yes |
132133

133134
#### PostgreSQL
134135
Parse Server is continuously tested with the most recent releases of PostgreSQL and PostGIS to ensure compatibility, using [PostGIS docker images](https://registry.hub.docker.com/r/postgis/postgis/tags?page=1&ordering=last_updated). We follow the [PostgreSQL support schedule](https://www.postgresql.org/support/versioning) and [PostGIS support schedule](https://www.postgis.net/eol_policy/) and only test against versions that are officially supported and have not reached their end-of-life date. Due to the extensive PostgreSQL support duration of 5 years, Parse Server drops support if a version is older than 3.5 years and a newer version has been available for at least 2.5 years.

spec/ParseQuery.hint.spec.js

+85-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ describe_only_db('mongo')('Parse.Query hint', () => {
122122
expect(queryPlanner.winningPlan.inputStage.inputStage.indexName).toBe('_id_');
123123
});
124124

125-
it_only_mongodb_version('>=5.1')('query aggregate with hint string', async () => {
125+
it_only_mongodb_version('>=5.1<5.2')('query aggregate with hint string', async () => {
126126
const object = new TestObject({ foo: 'bar' });
127127
await object.save();
128128

@@ -146,6 +146,30 @@ describe_only_db('mongo')('Parse.Query hint', () => {
146146
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.indexName).toBe('_id_');
147147
});
148148

149+
it_only_mongodb_version('>=5.2')('query aggregate with hint string', async () => {
150+
const object = new TestObject({ foo: 'bar' });
151+
await object.save();
152+
153+
const collection = await config.database.adapter._adaptiveCollection('TestObject');
154+
let result = await collection.aggregate([{ $group: { _id: '$foo' } }], {
155+
explain: true,
156+
});
157+
let queryPlanner = result[0].queryPlanner;
158+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
159+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('COLLSCAN');
160+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage).toBeUndefined();
161+
162+
result = await collection.aggregate([{ $group: { _id: '$foo' } }], {
163+
hint: '_id_',
164+
explain: true,
165+
});
166+
queryPlanner = result[0].queryPlanner;
167+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
168+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('FETCH');
169+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.stage).toBe('IXSCAN');
170+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.indexName).toBe('_id_');
171+
});
172+
149173
it_only_mongodb_version('<4.4')('query aggregate with hint object', async () => {
150174
const object = new TestObject({ foo: 'bar' });
151175
await object.save();
@@ -191,7 +215,7 @@ describe_only_db('mongo')('Parse.Query hint', () => {
191215
expect(queryPlanner.winningPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
192216
});
193217

194-
it_only_mongodb_version('>=5.1')('query aggregate with hint object', async () => {
218+
it_only_mongodb_version('>=5.1<5.2')('query aggregate with hint object', async () => {
195219
const object = new TestObject({ foo: 'bar' });
196220
await object.save();
197221

@@ -216,6 +240,31 @@ describe_only_db('mongo')('Parse.Query hint', () => {
216240
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
217241
});
218242

243+
it_only_mongodb_version('>=5.2')('query aggregate with hint object', async () => {
244+
const object = new TestObject({ foo: 'bar' });
245+
await object.save();
246+
247+
const collection = await config.database.adapter._adaptiveCollection('TestObject');
248+
let result = await collection.aggregate([{ $group: { _id: '$foo' } }], {
249+
explain: true,
250+
});
251+
let queryPlanner = result[0].queryPlanner;
252+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
253+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('COLLSCAN');
254+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage).toBeUndefined();
255+
256+
result = await collection.aggregate([{ $group: { _id: '$foo' } }], {
257+
hint: { _id: 1 },
258+
explain: true,
259+
});
260+
queryPlanner = result[0].queryPlanner;
261+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
262+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('FETCH');
263+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.stage).toBe('IXSCAN');
264+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.indexName).toBe('_id_');
265+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
266+
});
267+
219268
it_only_mongodb_version('<5.1')('query find with hint (rest)', async () => {
220269
const object = new TestObject();
221270
await object.save();
@@ -326,7 +375,7 @@ describe_only_db('mongo')('Parse.Query hint', () => {
326375
expect(queryPlanner.winningPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
327376
});
328377

329-
it_only_mongodb_version('>=5.1')('query aggregate with hint (rest)', async () => {
378+
it_only_mongodb_version('>=5.1<5.2')('query aggregate with hint (rest)', async () => {
330379
const object = new TestObject({ foo: 'bar' });
331380
await object.save();
332381
let options = Object.assign({}, masterKeyOptions, {
@@ -358,4 +407,37 @@ describe_only_db('mongo')('Parse.Query hint', () => {
358407
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.indexName).toBe('_id_');
359408
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
360409
});
410+
411+
it_only_mongodb_version('>=5.2')('query aggregate with hint (rest)', async () => {
412+
const object = new TestObject({ foo: 'bar' });
413+
await object.save();
414+
let options = Object.assign({}, masterKeyOptions, {
415+
url: Parse.serverURL + '/aggregate/TestObject',
416+
qs: {
417+
explain: true,
418+
group: JSON.stringify({ objectId: '$foo' }),
419+
},
420+
});
421+
let response = await request(options);
422+
let queryPlanner = response.data.results[0].queryPlanner;
423+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
424+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('COLLSCAN');
425+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage).toBeUndefined();
426+
427+
options = Object.assign({}, masterKeyOptions, {
428+
url: Parse.serverURL + '/aggregate/TestObject',
429+
qs: {
430+
explain: true,
431+
hint: '_id_',
432+
group: JSON.stringify({ objectId: '$foo' }),
433+
},
434+
});
435+
response = await request(options);
436+
queryPlanner = response.data.results[0].queryPlanner;
437+
expect(queryPlanner.winningPlan.queryPlan.stage).toBe('GROUP');
438+
expect(queryPlanner.winningPlan.queryPlan.inputStage.stage).toBe('FETCH');
439+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.stage).toBe('IXSCAN');
440+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.indexName).toBe('_id_');
441+
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
442+
});
361443
});

0 commit comments

Comments
 (0)