I have collection, as described below…
in my collection:
_id: ObjectId
locations: Array
location: Object (embedded)
type: "Point"
coordinates: Array
[ longitude, latitude ]
dates: Array
start_date: Date
note: String
I have successfully gotten the $geoNear
part of the aggregate()
working well now, but am confused about how to do date comparisons to further filter down the results.
My function arguments are longitude, latitude, max distance, and a date to be used. What I am wanting to do in the aggregate is simple,
$geoNear
, which is working fine for me
- match records where
start_date
< date passed as argument to function
OR - match records where
start_date
> date passed as argument, AND note != “” (empty)
I don’t seem to be able to do date comparisons, no matter where or what methods I’ve used. This includes:
-
using the
query
field in the$geoNear
aggregate stage (always the first in the pipeline) -
using
$match
as the next stage in the pipeline (after the$geoNear
without aquery
field set
I’ve tried using $expr
with $gte
as this is recommended in what I’ve read. I’ve also tried $cmp
with no success.
Here is the function and what I’m calling the function with, using the Atlas App Services Function Editor and Console:
From Atlas App Services Function Editor Console, I am testing with:
context.functions.execute("location_date", -80.130, 26.393, 10000, new Date("2023-02-01"), new Date("2023-02-28"))
exports = async function(longitude, latitude, searchRadius, startDate) {
var serviceName = "mongodb-atlas";
// Update these to reflect your db/collection
var dbName = "<my_database>"; // example, actual database name differs
var collName = "<my_collection>"; // example, actual collection name differs
// Get a collection from the context
var collection = context.services.get(serviceName).db(dbName).collection(collName);
// used to process results from the query
var findResult;
// set a date to the beginning of the year from the date sent in
var yearStartDate = new Date(startDate)
yearStartDate.setMonth(0);
yearStartDate.setDate(1);
yearStartDate.setHours(0);
yearStartDate.setMinutes(0);
yearStartDate.setSeconds(0);
//
// starting query here
try {
findResult = await collection.aggregate([
{ // begin pipeline for geoNear, always comes first for any aggregate pipeline
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude ]
}, // end near
"includeLocs": "locations.location",
"distanceField": "locations.distance",
"maxDistance": searchRadius,
"spherical": true
} // end $geoNear
}, // end 1st pipeline
{ // THIS DOESN'T SEEM EVALUATE THE DATE COMPARISONS
"$match": {
"$expr": {
"$gte": [ "locations.stella_event_dates.end_date", startDate ]
}
}
}, // end 2nd pipeline
{ // define fields we're excluding from being in the findResult
"$project": {
"event_name": 1,
"locations": 1,
} // end $project
}, // end 2nd pipeline
{ // for now, helping with the testing, by confirming date passed as arg is valid
"$addFields": {
"startDate": startDate.toDateString()
}
} // end 3rd pipeline
]
); // end .toArray().then()
} catch(err) {
console.log("Error occurred while executing find:", err.message);
return { error: err.message };
}
// To call other named functions:
// var result = context.functions.execute("function_name", arg1, arg2);
return { result: findResult };
};
What is the best way to compare dates in this function, (what am I doing wrong?)
Thanks