Skip to content

Commit 07f0d72

Browse files
mtrezzadblythy
authored andcommitted
feat: add MongoDB 5.2 support (parse-community#7894)
1 parent 74013c1 commit 07f0d72

File tree

4 files changed

+107
-18
lines changed

4 files changed

+107
-18
lines changed

.github/workflows/ci.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,18 @@ jobs:
142142
strategy:
143143
matrix:
144144
include:
145+
- name: MongoDB 5.2, ReplicaSet, WiredTiger
146+
MONGODB_VERSION: 5.2.1
147+
MONGODB_TOPOLOGY: replicaset
148+
MONGODB_STORAGE_ENGINE: wiredTiger
149+
NODE_VERSION: 14.18.1
145150
- name: MongoDB 5.1, ReplicaSet, WiredTiger
146-
MONGODB_VERSION: 5.1.0
151+
MONGODB_VERSION: 5.1.1
147152
MONGODB_TOPOLOGY: replicaset
148153
MONGODB_STORAGE_ENGINE: wiredTiger
149154
NODE_VERSION: 14.18.1
150155
- name: MongoDB 5.0, ReplicaSet, WiredTiger
151-
MONGODB_VERSION: 5.0.3
156+
MONGODB_VERSION: 5.0.6
152157
MONGODB_TOPOLOGY: replicaset
153158
MONGODB_STORAGE_ENGINE: wiredTiger
154159
NODE_VERSION: 16.13.0

README.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,14 @@ Parse Server is continuously tested with the most recent releases of Node.js to
136136

137137
#### MongoDB
138138

139-
| Version | Latest Version | End-of-Life | Compatible |
140-
|-------------|----------------|--------------|------------|
141-
| MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Yes |
142-
| MongoDB 4.2 | 4.2.17 | TBD | ✅ Yes |
143-
| MongoDB 4.4 | 4.4.10 | TBD | ✅ Yes |
144-
| MongoDB 5.0 | 5.0.3 | January 2024 | ✅ Yes |
145-
| MongoDB 5.1 | 5.1.0 | January 2024 | ✅ Yes |
139+
| Version | Latest Version | End-of-Life | Compatible |
140+
|-------------|----------------|-------------|------------|
141+
| MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Yes |
142+
| MongoDB 4.2 | 4.2.17 | TBD | ✅ Yes |
143+
| MongoDB 4.4 | 4.4.10 | TBD | ✅ Yes |
144+
| MongoDB 5.0 | 5.0.6 | TBD | ✅ Yes |
145+
| MongoDB 5.1 | 5.1.1 | TBD | ✅ Yes |
146+
| MongoDB 5.2 | 5.2.1 | TBD | ✅ Yes |
146147

147148
#### PostgreSQL
148149

package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,15 @@
125125
"test:mongodb:4.0.27": "npm run test:mongodb --dbversion=4.0.27",
126126
"test:mongodb:4.2.17": "npm run test:mongodb --dbversion=4.2.17",
127127
"test:mongodb:4.4.10": "npm run test:mongodb --dbversion=4.4.10",
128-
"test:mongodb:5.0.5": "npm run test:mongodb --dbversion=5.0.5",
129-
"test:mongodb:5.1.0": "npm run test:mongodb --dbversion=5.1.0",
128+
"test:mongodb:5.0.6": "npm run test:mongodb --dbversion=5.0.6",
129+
"test:mongodb:5.1.1": "npm run test:mongodb --dbversion=5.1.1",
130+
"test:mongodb:5.2.1": "npm run test:mongodb --dbversion=5.2.1",
130131
"posttest:mongodb": "mongodb-runner stop",
131-
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.1.0} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start",
132-
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.1.0} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine",
132+
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.2.1} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner start",
133+
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.2.1} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 jasmine",
133134
"test": "npm run testonly",
134-
"posttest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.1.0} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner stop",
135-
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.1.0} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 nyc jasmine",
135+
"posttest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.2.1} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} mongodb-runner stop",
136+
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.2.1} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} MONGODB_STORAGE_ENGINE=${MONGODB_STORAGE_ENGINE:=wiredTiger} TESTING=1 nyc jasmine",
136137
"start": "node ./bin/parse-server",
137138
"prettier": "prettier --write {src,spec}/{**/*,*}.js",
138139
"prepare": "npm run build",

spec/ParseQuery.hint.spec.js

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

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

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

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

196-
it_only_mongodb_version('>=5.1')('query aggregate with hint object', async () => {
220+
it_only_mongodb_version('>=5.1<5.2')('query aggregate with hint object', async () => {
197221
const object = new TestObject({ foo: 'bar' });
198222
await object.save();
199223

@@ -218,6 +242,31 @@ describe_only_db('mongo')('Parse.Query hint', () => {
218242
expect(queryPlanner.winningPlan.queryPlan.inputStage.inputStage.keyPattern).toEqual({ _id: 1 });
219243
});
220244

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

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

0 commit comments

Comments
 (0)