From 95d56c2111dd90eb2acb412ffbfae649e5b2ff1c Mon Sep 17 00:00:00 2001 From: Matthieu Date: Thu, 4 Jul 2024 16:10:25 -0400 Subject: [PATCH] feat: front mongo search with geoWithin --- .../latestTaxiPosition.repository.ts | 46 +++++++++++++------ .../shared/commonLoadTests/specialRegion.ts | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/le-taxi-api-node.js/src/features/latestTaxiPositions/latestTaxiPosition.repository.ts b/le-taxi-api-node.js/src/features/latestTaxiPositions/latestTaxiPosition.repository.ts index f342762..15398e1 100644 --- a/le-taxi-api-node.js/src/features/latestTaxiPositions/latestTaxiPosition.repository.ts +++ b/le-taxi-api-node.js/src/features/latestTaxiPositions/latestTaxiPosition.repository.ts @@ -12,6 +12,9 @@ import { LatestTaxiPositionModelExtended, } from "./latestTaxiPosition.model"; +// https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2d/calculate-distances/#convert-kilometers-to-radians +const meterToRadianRatio = 6378100; + class LatestTaxiPositionRepository { public async findClosestTaxis( coordinate: ICoordinates, @@ -20,21 +23,36 @@ class LatestTaxiPositionRepository { ): Promise { const db = getMongoDb(); - const filters = inquiryTypes.map((inquiryType) => ({ - isPromoted: true, - status: TaxiStatus.Free, - ...operatorsCondition(operators), - ...transportationTypeCondition(inquiryType), - location: { - $near: { - $geometry: { - type: "Point", - coordinates: [coordinate.lon, coordinate.lat], + const point = [coordinate.lon, coordinate.lat]; + const filters = inquiryTypes.map((inquiryType) => { + const radius = getArbitraryMaxDistance(inquiryType); + return { + isPromoted: true, + status: TaxiStatus.Free, + ...operatorsCondition(operators), + ...transportationTypeCondition(inquiryType), + $and: [ + { + location: { + $geoWithin: { + $centerSphere: [point, radius / meterToRadianRatio], + }, + }, }, - $maxDistance: getArbitraryMaxDistance(inquiryType), - }, - }, - })); + { + location: { + $near: { + $geometry: { + type: "Point", + coordinates: point, + }, + $maxDistance: radius, + }, + }, + }, + ], + }; + }); const results = await Promise.all( filters.map((filter) => diff --git a/le-taxi-api-tests/src/shared/commonLoadTests/specialRegion.ts b/le-taxi-api-tests/src/shared/commonLoadTests/specialRegion.ts index 1317f89..9c3a5a2 100644 --- a/le-taxi-api-tests/src/shared/commonLoadTests/specialRegion.ts +++ b/le-taxi-api-tests/src/shared/commonLoadTests/specialRegion.ts @@ -27,7 +27,7 @@ export function generateApiTestCoordinates(): ICoordinates { return { lat: generateLatForApiTest(), lon: generateLonForApiTest() }; } -export function generatePointsForLoadTest(count: number = 1): ICoordinates { +export function generatePointsForLoadTest(count: number = 1): ICoordinates[] { const features = randomPointsOnPolygon(count, montrealPolygon); const points = features.map((feature: any) => { const point = feature.geometry.coordinates;