Turistforeningen / node-mongo-querystring

Query builder for accepting URL query parameters into your MongoDB queries. Safe and feature rich. Supports most of MongoDB's query operators such as $eq, $gt, $lt, $ne, $in, $nin, $exists, $regex, geospatial queries such as bbox and near, as well as your own custom query business logic!
MIT License
100 stars 31 forks source link

Custom near query not working #65

Open joshkopecek opened 7 years ago

joshkopecek commented 7 years ago

I'm having a problem with the custom near query again, using v4.4.1 If I specify a name for the query like so:

custom: {
    …
    near: 'loc'
}

It throws an error from Mongo:

error processing query: ns=echoesfullstack-dev.collections limit=10Tree: $and    pub_status == \"public\"
    GEONEAR  field=(query, point) => {
  const pointArr = point.split(',').map(p => parseFloat(p, 10));

  if (pointArr.length >= 2) {
    if (!isNaN(pointArr.reduce((a, b) => a + b))) {
      const max = pointArr[2];
      const min = pointArr[3];

      query[field] = {
        $near: {
          $geometry: {
            type: 'Point',
            coordinates: pointArr.splice(0, 2),
          },
        },
      };

      if (!isNaN(max)) {
        query[field].$near.$maxDistance = max;

        if (!isNaN(min)) {
          query[field].$near.$minDistance = min;
        }
      }
    }
  }
} maxdist=1.79769e+308 isNearSphere=0
Sort: {}
Proj: {}
 planner returned error: unable to find index for $geoNear query

It seems to be returning the entire function as a query. Is that expected behaviour?

I manually overrode the query with :

if (query.near) {
    let pointArr = req.query.near.split(',').map(p => parseFloat(p, 10));
    let n = {
      $near: {
        $geometry: {
          type: 'Point',
          coordinates: pointArr.splice(0, 2),
        }
      }
    };
    // maybe we have $maxDistance
    if (pointArr.length)
      n.$near.$maxDistance = parseFloat(pointArr.shift());
    delete query.near
    query.loc = n;
  }

and it now works fine for me.

Starefossen commented 7 years ago

Hmmm... that's odd. Take a look at the unit test for near and you can see that it is supposed to only return a JSON output.

The error also says that mongoDB is unable to find a geospatial index for the $geoNear query. Have you added the index to the loc field?

joshkopecek commented 7 years ago

Definitely have an index for the loc, since the subsequent manually-created query works fine. Also was working up until I upgraded to 4.x (AFAIK).

I will check the unit tests and report again.

Starefossen commented 7 years ago

Thanks. Also, just try to run this:

const mqs = new MongoQS({
  custom: {
    near: 'loc',
  },
});

console.log(mqs.parse({ loc: '1,2' }));
joshkopecek commented 7 years ago

Ok it looks like this is my mistake, something else weird is going on with a destructure operation. That does actually work, (replacing the query with {near: '1,2'} ).

Thanks for your time.

Starefossen commented 7 years ago

No problem, glad we could sort this out. Please report back if you find any errors with the code so we can fix them.