Can't use $geoNear with NestJS and Mongoose

Viewed 1223

I'm stuck trying to solve a geospatial query with NestJS and Mongoose. I have done so many attempts that right now I can't even remember all of them, but now my code looks like this:

// application.module.ts
@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/<DATABASE_NAME>', {
      useCreateIndex: true,
      useNewUrlParser: true,
      useUnifiedTopology: true
    }
 ]
})
// restaurants.schema.ts
import { v4 } from 'uuid';
import { Schema } from 'mongoose';

const RestaurantsSchema = new Schema({
  _id: {
    type: String,
    default: v4
  },
  name: {
    type: String,
    required: true
  },
  location: {
    type: {
      type: String,
      enum: ['Point'],
      default: 'Point',
      required: true
    },
    coordinates: {
      type: [Number],
      required: true,
      index: '2dsphere'
    }
  }
}, {
  timestamps: true
});

export { RestaurantsSchema };

I inserted some records on restaurants collection with restaurantModel: Model<IRestaurant>. Then, when I aggregate from mongo, I get the result:

> db.restaurants.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "<DATABASE_NAME>.restaurants"
    },
    {
        "v" : 2,
        "key" : {
            "location.coordinates" : "2dsphere"
        },
        "name" : "location.coordinates_2dsphere",
        "ns" : "<DATABASE_NAME>.restaurants",
        "background" : true,
        "2dsphereIndexVersion" : 3
    }
]

> db.restaurants.aggregate([{ $geoNear: { near: { type: "Point", coordinates: [-46.6954844,-23.5006969] }, distanceField: "distanceFromMe", maxDistance: 1000 * 1609.34, distanceMultiplier: 1 / 1609.34, spherical: true } }]).pretty()
{
    "_id" : "011deea3-415b-45d9-90dd-097e9f689a2b",
    "location" : {
        "type" : "Point",
        "coordinates" : [
            -46.6954844,
            -23.6006969
        ]
    },
    "name" : "Dona So",
    "createdAt" : ISODate("2020-02-28T02:40:28.493Z"),
    "updatedAt" : ISODate("2020-02-28T02:40:28.493Z"),
    "__v" : 0,
    "distanceFromMe" : 6.917049537167114
}

Seems to be working fine. But, when I try to do the same with Mongoose:

// restaurants.repository.ts
public async getNear(longitude: Number, latitude: Number, maxDistance: Number): Promise<IRestaurantModel[]> {
  const restaurants = await this.restaurantModel.aggregate([
    {
      $geoNear: {
        near: {
          type: 'Point',
          coordinates: [longitude, latitude]
        },
        distanceField: 'distanceFromMe',
        maxDistance: 1000 * 1609.34,
        distanceMultiplier: 1 / 1609.34,
        spherical: true,
      }
    }
 ]);
 return restaurants;
}

Output:

ok: 0,
  errmsg: 'Failed to determine whether query system can provide a covered ' +
    'projection :: caused by :: geo near accepts just one argument when ' +
    'querying for a GeoJSON point. Extra field found: $maxDistance: ' +
    '1609340.0',
  code: 2,
  codeName: 'BadValue',
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {}

Now I can't even know where exactly the error is. I also tried to use aggregate().near() from mongoose.

Some versions I am using:

  • Node: v12.0.0
  • npm: 6.9.0
  • @nestjs/mongoose: 6.1.2
  • mongoose: 5.9.2
  • mongo: 4.2.1
0 Answers
Related