From 5fd73a72fd1280f19d82a754722c2fddfc72f312 Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 8 Sep 2020 22:16:03 +0200 Subject: [PATCH] fix potential issue with setting geoNear.query to undefined (#6696) * add test cases for geoNear aggregation Test cases do not have the `query` parameter set in $geoNear aggregation stage. this is to test for a reported potential issue when the parameter is not set. * fixed potential issue when setting the geoNear.query parameter to undefined see dicussion in https://github.com/parse-community/parse-server/pull/6540 * fixed duplicate index name in test --- spec/ParseQuery.Aggregate.spec.js | 77 ++++++++++++++++++- .../Storage/Mongo/MongoStorageAdapter.js | 2 +- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index d9a684d0..83a3d796 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -1430,7 +1430,7 @@ describe('Parse.Query Aggregate testing', () => { } ); - it_only_db('mongo')('geoNear with location query', async () => { + it_only_db('mongo')('aggregate geoNear with location query', async () => { // Create geo index which is required for `geoNear` query const database = Config.get(Parse.applicationId).database; const schema = await new Parse.Schema('GeoObject').save(); @@ -1438,7 +1438,7 @@ describe('Parse.Query Aggregate testing', () => { 'GeoObject', schema, ['location'], - 'geoIndex', + undefined, false, { indexType: '2dsphere' }, ); @@ -1474,4 +1474,77 @@ describe('Parse.Query Aggregate testing', () => { expect(results[0].value).toEqual(2); expect(results[1].value).toEqual(3); }); + + it_only_db('mongo')('aggregate geoNear with near GeoJSON point', async () => { + // Create geo index which is required for `geoNear` query + const database = Config.get(Parse.applicationId).database; + const schema = await new Parse.Schema('GeoObject').save(); + await database.adapter.ensureIndex( + 'GeoObject', + schema, + ['location'], + undefined, + false, + '2dsphere' + ); + // Create objects + const GeoObject = Parse.Object.extend('GeoObject'); + const obj1 = new GeoObject({ value: 1, location: new Parse.GeoPoint(1, 1), date: new Date(1) }); + const obj2 = new GeoObject({ value: 2, location: new Parse.GeoPoint(2, 1), date: new Date(2) }); + const obj3 = new GeoObject({ value: 3, location: new Parse.GeoPoint(3, 1), date: new Date(3) }); + await Parse.Object.saveAll([obj1, obj2, obj3]); + // Create query + const pipeline = [ + { + geoNear: { + near: { + type: 'Point', + coordinates: [1, 1] + }, + key: 'location', + spherical: true, + distanceField: 'dist' + } + } + ]; + const query = new Parse.Query(GeoObject); + const results = await query.aggregate(pipeline); + // Check results + expect(results.length).toEqual(3); + }); + + it_only_db('mongo')('aggregate geoNear with near legacy coordinate pair', async () => { + // Create geo index which is required for `geoNear` query + const database = Config.get(Parse.applicationId).database; + const schema = await new Parse.Schema('GeoObject').save(); + await database.adapter.ensureIndex( + 'GeoObject', + schema, + ['location'], + undefined, + false, + '2dsphere' + ); + // Create objects + const GeoObject = Parse.Object.extend('GeoObject'); + const obj1 = new GeoObject({ value: 1, location: new Parse.GeoPoint(1, 1), date: new Date(1) }); + const obj2 = new GeoObject({ value: 2, location: new Parse.GeoPoint(2, 1), date: new Date(2) }); + const obj3 = new GeoObject({ value: 3, location: new Parse.GeoPoint(3, 1), date: new Date(3) }); + await Parse.Object.saveAll([obj1, obj2, obj3]); + // Create query + const pipeline = [ + { + geoNear: { + near: [1, 1], + key: 'location', + spherical: true, + distanceField: 'dist' + } + } + ]; + const query = new Parse.Query(GeoObject); + const results = await query.aggregate(pipeline); + // Check results + expect(results.length).toEqual(3); + }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 9e75f5bb..c7f35263 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -860,7 +860,7 @@ export class MongoStorageAdapter implements StorageAdapter { stage.$project ); } - if (stage.$geoNear) { + if (stage.$geoNear && stage.$geoNear.query) { stage.$geoNear.query = this._parseAggregateArgs( schema, stage.$geoNear.query