无法将 $geoNear 与 NestJS 和 Mongoose 一起使用

问题描述 投票:0回答:1

我一直在尝试使用 NestJS 和 Mongoose 解决地理空间查询。我已经做了很多尝试,现在我什至记不清所有的尝试,但现在我的代码如下所示:

// 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 };

我用

restaurants
restaurantModel: Model<IRestaurant>
集合中插入了一些记录。然后,当我从 mongo 聚合时,我得到结果:

> 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
}

看起来工作正常。但是,当我尝试对 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;
}

输出:

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)]: {}

现在我什至不知道错误到底在哪里。我还尝试使用猫鼬的

aggregate().near()

我正在使用的一些版本:

  • 节点:v12.0.0
  • npm:6.9.0
  • @nestjs/猫鼬:6.1.2
  • 猫鼬:5.9.2
  • 蒙戈:4.2.1
mongodb mongoose geospatial nestjs
1个回答
0
投票

您可能看过这个或类似的指南:https://www.slingacademy.com/article/how-to-use-geolocation-in-mongoose-with-examples/ 。 虽然正确,但它添加了一些嵌套,如果没有必要,您不必使用它们。 您可以在任何内部有两个数字且索引为 '2d' 的字段上使用 $near。 我将 NestJs 与猫鼬一起使用,以下对我有用:

架构定义:

@Schema({ timestamps: true })
export class ClassName extends Document {

 @Prop({ required: [true, 'In Schema: Title is required!'] })
 title: string;

 @Prop({ required: [true, 'In Schema: Coordinates are required!'], index: '2d' })
 coordinates: number[];
};

export const SchemaName = SchemaFactory.createForClass(ClassName);

查询:

const queryOptions = {
         coordinates: {
           $near: [-75 , 32], // lat & lng must be in reverse for query
           $maxDistance: 1000, // in meters
         },
       };

await this.modelName.find(queryOptions);

这将查找坐标在 1000 米范围内的条目。结果按从最接近到最远的顺序排序。

© www.soinside.com 2019 - 2024. All rights reserved.