feat(AggregateRouter): support native mongodb syntax in aggregation pipelines (#7339)

This commit is contained in:
Raschid J.F. Rafeally
2021-08-12 12:14:04 -05:00
committed by GitHub
parent 381e9bf014
commit 8fddac39bf
5 changed files with 127 additions and 41 deletions

View File

@@ -1,6 +1,7 @@
const AggregateRouter = require('../lib/Routers/AggregateRouter').AggregateRouter;
describe('AggregateRouter', () => {
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Array', () => {
const body = [
{
@@ -12,6 +13,7 @@ describe('AggregateRouter', () => {
expect(result).toEqual(expected);
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Object', () => {
const body = {
group: { objectId: {} },
@@ -21,6 +23,7 @@ describe('AggregateRouter', () => {
expect(result).toEqual(expected);
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Pipeline Operator (Array)', () => {
const body = {
pipeline: [
@@ -34,6 +37,7 @@ describe('AggregateRouter', () => {
expect(result).toEqual(expected);
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline from Pipeline Operator (Object)', () => {
const body = {
pipeline: {
@@ -45,6 +49,7 @@ describe('AggregateRouter', () => {
expect(result).toEqual(expected);
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline fails multiple keys in Array stage ', () => {
const body = [
{
@@ -59,6 +64,7 @@ describe('AggregateRouter', () => {
}
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get pipeline fails multiple keys in Pipeline Operator Array stage ', () => {
const body = {
pipeline: [
@@ -75,6 +81,7 @@ describe('AggregateRouter', () => {
}
});
// TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx)
it('get search pipeline from Pipeline Operator (Array)', () => {
const body = {
pipeline: {
@@ -85,4 +92,73 @@ describe('AggregateRouter', () => {
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});
it('support stage name starting with `$`', () => {
const body = {
$match: { someKey: 'whatever' },
};
const expected = [{ $match: { someKey: 'whatever' } }];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});
it('support nested stage names starting with `$`', () => {
const body = [
{
lookup: {
from: 'ACollection',
let: { id: '_id' },
as: 'results',
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$id'],
},
},
},
],
},
},
];
const expected = [
{
$lookup: {
from: 'ACollection',
let: { id: '_id' },
as: 'results',
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$id'],
},
},
},
],
},
},
];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});
it('support the use of `_id` in stages', () => {
const body = [
{ match: { _id: 'randomId' } },
{ sort: { _id: -1 } },
{ addFields: { _id: 1 } },
{ group: { _id: {} } },
{ project: { _id: 0 } },
];
const expected = [
{ $match: { _id: 'randomId' } },
{ $sort: { _id: -1 } },
{ $addFields: { _id: 1 } },
{ $group: { _id: {} } },
{ $project: { _id: 0 } },
];
const result = AggregateRouter.getPipeline(body);
expect(result).toEqual(expected);
});
});

View File

@@ -23,28 +23,28 @@ const loadTestData = () => {
const data1 = {
score: 10,
name: 'foo',
sender: { group: 'A' },
sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx)
views: 900,
size: ['S', 'M'],
};
const data2 = {
score: 10,
name: 'foo',
sender: { group: 'A' },
sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx)
views: 800,
size: ['M', 'L'],
};
const data3 = {
score: 10,
name: 'bar',
sender: { group: 'B' },
sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx)
views: 700,
size: ['S'],
};
const data4 = {
score: 20,
name: 'dpl',
sender: { group: 'B' },
sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx)
views: 700,
size: ['S'],
};
@@ -83,22 +83,10 @@ describe('Parse.Query Aggregate testing', () => {
);
});
it('invalid query group _id', done => {
it('invalid query group _id required', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
group: { _id: null },
},
});
get(Parse.serverURL + '/aggregate/TestObject', options).catch(error => {
expect(error.error.code).toEqual(Parse.Error.INVALID_QUERY);
done();
});
});
it('invalid query group objectId required', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
group: {},
group: {}, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
});
get(Parse.serverURL + '/aggregate/TestObject', options).catch(error => {
@@ -110,7 +98,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group by field', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
group: { objectId: '$name' },
group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
});
get(Parse.serverURL + '/aggregate/TestObject', options)
@@ -131,7 +119,7 @@ describe('Parse.Query Aggregate testing', () => {
const options = Object.assign({}, masterKeyOptions, {
body: {
pipeline: {
group: { objectId: '$name' },
group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
},
});
@@ -149,7 +137,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj = new TestObject();
const pipeline = [
{
group: { objectId: {} },
group: { objectId: {} }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
];
obj
@@ -168,7 +156,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj = new TestObject();
const pipeline = [
{
group: { objectId: '' },
group: { objectId: '' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
];
obj
@@ -187,7 +175,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj = new TestObject();
const pipeline = [
{
group: { objectId: [] },
group: { objectId: [] }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx)
},
];
obj
@@ -208,6 +196,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj3 = new TestObject();
const pipeline = [
{
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: {
objectId: {
score: '$score',
@@ -234,6 +223,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj3 = new TestObject();
const pipeline = [
{
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: {
objectId: {
day: { $dayOfMonth: '$_updated_at' },
@@ -264,6 +254,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj3 = new TestObject();
const pipeline = [
{
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: {
objectId: {
day: { $dayOfMonth: '$updatedAt' },
@@ -291,7 +282,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group by number', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
group: { objectId: '$score' },
group: { objectId: '$score' }, // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
},
});
get(Parse.serverURL + '/aggregate/TestObject', options)
@@ -313,6 +304,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 });
const pipeline = [
{
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: {
objectId: null,
total: { $sum: { $multiply: ['$quantity', '$price'] } },
@@ -372,7 +364,7 @@ describe('Parse.Query Aggregate testing', () => {
},
{
project: {
objectId: 0,
objectId: 0, // TODO: change to `_id`. See [#7339](https://bit.ly/3incnWx)
total: { $multiply: ['$quantity', '$price'] },
},
},
@@ -459,6 +451,7 @@ describe('Parse.Query Aggregate testing', () => {
const obj3 = new TestObject({ dateField2019: new Date(1990, 11, 1) });
const pipeline = [
{
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: {
objectId: {
day: { $dayOfMonth: '$dateField2019' },
@@ -508,6 +501,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group sum query', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, total: { $sum: '$score' } },
},
});
@@ -524,6 +518,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group count query', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, total: { $sum: 1 } },
},
});
@@ -540,6 +535,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group min query', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, minScore: { $min: '$score' } },
},
});
@@ -556,6 +552,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group max query', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, maxScore: { $max: '$score' } },
},
});
@@ -572,6 +569,7 @@ describe('Parse.Query Aggregate testing', () => {
it('group avg query', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, avgScore: { $avg: '$score' } },
},
});
@@ -1017,6 +1015,7 @@ describe('Parse.Query Aggregate testing', () => {
const options = Object.assign({}, masterKeyOptions, {
body: {
project: { score: 1 },
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: '$score', score: { $sum: '$score' } },
},
});
@@ -1044,6 +1043,7 @@ describe('Parse.Query Aggregate testing', () => {
it('class does not exist return empty', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, total: { $sum: '$score' } },
},
});
@@ -1058,6 +1058,7 @@ describe('Parse.Query Aggregate testing', () => {
it('field does not exist return empty', done => {
const options = Object.assign({}, masterKeyOptions, {
body: {
// TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx)
group: { objectId: null, total: { $sum: '$unknownfield' } },
},
});