I’m working with this schema:
const mongoose = require("mongoose");
const { rideStatus } = require("../utils/rideStatus")
const rideSchema = new mongoose.Schema(
{
departureTime: {
type: Date,
required: true,
},
driverId: {
type: mongoose.Types.ObjectId,
ref: "User",
},
vehicleId: {
type: mongoose.Types.ObjectId,
ref: "Vehicle",
required: true,
},
from: {
type: String,
required: true,
},
fromCoordinates: {
type: {
type: String,
default: "Point",
},
coordinates: {
type: [Number],
required: true,
},
},
to: {
type: String,
required: true,
},
toCoordinates: {
type: {
type: String,
default: "Point",
},
coordinates: {
type: [Number],
default: undefined,
required: true,
},
},
estimatedTravelTime: {
type: Number,
required: true,
},
travelTimeTaken:{
type: Number,
},
distanceTraveled:{
type: Number,
},
maxWaitTime: {
type: Number,
required: true,
},
availableSeats: {
type: Number,
required: true,
},
pricePerSeat: {
type: mongoose.Types.Decimal128,
required: true,
},
showRange: {
type: Number,
required: true,
},
rideId: {
type: Number,
},
status: {
type: String,
enum: Object.values(rideStatus),
default: rideStatus.PENDING,
},
},
{
timestamps: true,
}
);
rideSchema.index({fromCoordinates: "2dsphere"})
rideSchema.index({toCoordinates: "2dsphere"})
const Ride = mongoose.model("Ride", rideSchema);
module.exports = Ride;
And I’m trying to build a search query that recieves user coordinates, and a search range, it should meet the next requirements:
Calculate distance between user and ride, it should only return those rides that are inside ride showRange attribute and user search range recieved from the request. Both range attributes are specified in meters.
It should behave like this:
If I make a request with the following data:
{
latitude: 41.92821718813537,
longitude: 12.466890164886028,
searchRange: 5000
}
It should return the next ride:
{
"message": "ok",
"data": {
"departureTime": "2030-06-15T00:00:00.000Z",
"driverId": "660345ead20962addf1499b8",
"vehicleId": "660e8d3dbfc368fa5cc02260",
"from": "FROM TEST",
"fromCoordinates": {
"coordinates": [
41.90392093563473,
12.453128679058644
],
"type": "Point"
},
"to": "TO TEST",
"toCoordinates": {
"coordinates": [
41.808967733729155,
12.264034374847718
],
"type": "Point"
},
"estimatedTravelTime": 2,
"maxWaitTime": 15,
"availableSeats": 3,
"pricePerSeat": {
"$numberDecimal": "500.5"
},
"showRange": 5000,
"status": "PENDING",
"_id": "6627a145674cfa6e0cbaf7e8",
"rideId": 62
}
}
Both, user search range and ride search range are within their respective radius as they are only 3km away from each other.
If I make a request with the following data:
{
latitude: 41.92821718813537,
longitude: 12.466890164886028,
searchRange: 1000
}
It should return a 404 code, ride is outside user search range radius.
Also if I modifiy ride document and set showRange attribute to 1000
{
"message": "ok",
"data": {
"departureTime": "2030-06-15T00:00:00.000Z",
"driverId": "660345ead20962addf1499b8",
"vehicleId": "660e8d3dbfc368fa5cc02260",
"from": "FROM TEST",
"fromCoordinates": {
"coordinates": [
41.90392093563473,
12.453128679058644
],
"type": "Point"
},
"to": "TO TEST",
"toCoordinates": {
"coordinates": [
41.808967733729155,
12.264034374847718
],
"type": "Point"
},
"estimatedTravelTime": 2,
"maxWaitTime": 15,
"availableSeats": 3,
"pricePerSeat": {
"$numberDecimal": "500.5"
},
"showRange": 1000,
"status": "PENDING",
"_id": "6627a145674cfa6e0cbaf7e8",
"rideId": 62
}
}
And do the first example request
{
latitude: 41.92821718813537,
longitude: 12.466890164886028,
searchRange: 5000
}
It should return a 404 code as user is outside ride showRange radius.
Tried a combination of multiple mongoDb geo json methods like $maxDistance, $geometry, $geoWithin, $centerSphere, etc. but can’t structure a query that succesfully meets the expected response.
Also tried using $where but got this error:
$where not allowed in this atlas tier
As I’m hosting my db on a free cluster it seems I have to pay to use that feature.