diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index f68d76a4..b7dd291d 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -1,6 +1,7 @@ 'use strict'; const Parse = require('parse/node'); const request = require('../lib/request'); +const Config = require('../lib/Config'); const masterKeyHeaders = { 'X-Parse-Application-Id': 'test', @@ -1428,4 +1429,49 @@ describe('Parse.Query Aggregate testing', () => { }); } ); + + it_only_db('mongo')('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(); + await database.adapter.ensureIndex( + 'GeoObject', + schema, + ['location'], + 'geoIndex', + 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', + query: { + date: { + $gte: new Date(2) + } + } + } + } + ]; + const query = new Parse.Query(GeoObject); + const results = await query.aggregate(pipeline); + // Check results + expect(results.length).toEqual(2); + expect(results[0].value).toEqual(2); + expect(results[1].value).toEqual(3); + }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index b6902fd7..a5107a90 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -682,7 +682,8 @@ export class MongoStorageAdapter implements StorageAdapter { schema: SchemaType, fieldNames: string[], indexName: ?string, - caseInsensitive: boolean = false + caseInsensitive: boolean = false, + indexType: any = 1 ): Promise { schema = convertParseSchemaToMongoSchema(schema); const indexCreationRequest = {}; @@ -690,7 +691,7 @@ export class MongoStorageAdapter implements StorageAdapter { transformKey(className, fieldName, schema) ); mongoFieldNames.forEach(fieldName => { - indexCreationRequest[fieldName] = 1; + indexCreationRequest[fieldName] = indexType; }); const defaultOptions: Object = { background: true, sparse: true }; @@ -843,6 +844,9 @@ export class MongoStorageAdapter implements StorageAdapter { stage.$project ); } + if (stage.$geoNear) { + stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query); + } return stage; }); readPreference = this._parseReadPreference(readPreference); diff --git a/src/Adapters/Storage/StorageAdapter.js b/src/Adapters/Storage/StorageAdapter.js index ca4b406b..0256841b 100644 --- a/src/Adapters/Storage/StorageAdapter.js +++ b/src/Adapters/Storage/StorageAdapter.js @@ -92,7 +92,8 @@ export interface StorageAdapter { schema: SchemaType, fieldNames: string[], indexName?: string, - caseSensitive?: boolean + caseSensitive?: boolean, + indexType?: any ): Promise; ensureUniqueness( className: string,