Я застрял, пытаясь решить геопространственный запрос с помощью Nest JS и Mon goose. Я сделал так много попыток, что сейчас я не могу даже вспомнить их все, но теперь мой код выглядит так:
// 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>
. Затем, когда я агрегирую с mon go, я получаю результат:
> 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
}
Кажется, работает нормально. Но когда я пытаюсь сделать то же самое с Mon goose:
// 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()
из mon goose.
Некоторые версии, которые я использую:
- Узел: v12.0.0
- npm: 6.9.0
- @ nestjs / mon goose: 6.1.2
- mon goose: 5.9.2
- mon go: 4.2.1