node.jsmongodbexpressaggregation-frameworkgeonear

MongoDB geoNear not working for some coordinates but working for others


I'm working on an API using MongoDB and the Node.js driver for mongoDB. One of the routes takes in coordinates and calls an aggregation pipeline that returns results sorted by closeness and a number of other factors. The code for the first step of the pipeline is:

{$geoNear:{
  near:{
     type: "Point",
     coordinates: [lat, long]
  },
  spherical:true,
  distanceField:"distance"
}},

This was working fine until all of the sudden, it wasn't. Now it works for some coordinates and for others it gives the error MongoError: invalid argument in geo near query: type. It works fine with {lat:0, long:0}, fine with {lat:40.7411, long:-73.9897}, fine with {lat:46.68758191106798, long:2.8106467331441767}, but gives the error with {lat:37.785834, long:-122.406417} and {lat:47.643628614308675, long:-122.34560056016635}. The only pattern I can find is that it hates coordinates on the West Coast. I've verified that the 2d-sphere index is still there on the data. I've tried setting spherical to false. I've even tried deleting all the data, and still get the same behavior even with an empty collection. I'm truly mystified as to why the argument to geonear would be valid for some points and not for others.

Edit: I've now commented out everything except for the following code and I'm still getting the same behavior where some coordinates work and others give MongoError: invalid argument in geo near query: type

router.post("/", asyncHandler(async (req, res, next) => {
    const {lat, long} = req.body;
    const errors = [];
    if(typeof(lat) !== "number" || Math.abs(lat) > 90) errors.push("Lat is invalid");
    if(typeof(long) !== "number" || Math.abs(long) > 180) errors.push("Long is invalid");
    if(errors.length) return next(errors);
    const feed = await req.app.locals.db.collection("posts").aggregate(
        [
            {$geoNear:{
                near:{
                    type: "Point",
                    coordinates: [lat, long]
                },
                spherical:true,
                distanceField:"distance"
            }},
        ]
    );
    const feedArr = await feed.toArray();
    res.json(feedArr);
}));

Solution

  • See GeoJSON Objects:

    If specifying latitude and longitude coordinates, list the longitude first and then latitude

    You did coordinates: [lat, long]