我正在尝试为2dSphere
中存在的字段startLocation
添加tourSchema
索引。这是下面的样子
startLocation: {
type: {
type: String,
default: 'Point',
enum: ['Point']
},
coordinates: [Number],
address: String,
description: String
}
您还可以在下面看到我在此架构上添加索引的方式和方式
tourSchema.index({price:1,ratingsAverage:-1});
tourSchema.index({slug:1});
tourSchema.index({ startLocation: '2dsphere' });
很遗憾,Mongodb
无法识别startLocation
索引。使用Mongo Compass
,我可以查看除startLocation:'2dsphere'.
这是邮递员在向控制器中的getDistances
方法发送请求时出现的以下错误:
{
"status": "error",
"error": {
"operationTime": "6791492473605586945",
"ok": 0,
"errmsg": "$geoNear requires a 2d or 2dsphere index, but none were found",
"code": 27,
"codeName": "IndexNotFound",
"$clusterTime": {
"clusterTime": "6791492473605586945",
"signature": {
"hash": "4LYCSBslSoLAoqj93bLXmpubBxs=",
"keyId": "6779443539857113090"
}
},
"name": "MongoError",
"statusCode": 500,
"status": "error"
},
"message": "$geoNear requires a 2d or 2dsphere index, but none were found",
"stack": "MongoError: $geoNear requires a 2d or 2dsphere index, but none were found\n at Connection.<anonymous> (C:\\Users\\timuc\\Downloads\\starter\\starter\\node_modules\\mongodb-core\\lib\\connection\\pool.js:443:61)\n at Connection.emit (events.js:223:5)\n at processMessage (C:\\Users\\timuc\\Downloads\\starter\\starter\\node_modules\\mongodb-core\\lib\\connection\\connection.js:364:10)\n at TLSSocket.<anonymous> (C:\\Users\\timuc\\Downloads\\starter\\starter\\node_modules\\mongodb-core\\lib\\connection\\connection.js:533:15)\n at TLSSocket.emit (events.js:223:5)\n at addChunk (_stream_readable.js:309:12)\n at readableAddChunk (_stream_readable.js:290:11)\n at TLSSocket.Readable.push (_stream_readable.js:224:10)\n at TLSWrap.onStreamRead (internal/stream_base_commons.js:181:23)"
}
我试图添加point: '2dsphere'
,这被mongodb识别,但是我不满意。因为当我向控制器中的方法发送请求时,该方法返回成功但具有空数组。
这是在控制器中触发的方法:
exports.getDistances = catchAsync(async (req, res, next) => {
const { latlng, unit } = req.params;
const [lat, lng] = latlng.split(",");
if (!lat || !lng) {
new AppError( "Please provide latitude and longitude in the format lat,lng", 400);
}
const distances = await Tour.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [lng * 1, lat * 1]
},
distanceField: "distance"
}
}
]);
res.status(200).json({
status: "success",
data: {
data: distances
}
});
});
也可以从路由器上看到我如何在下面发送请求网址
tourRouter.route('/distances/:latlng/unit/:unit').get(tourController.getDistances);
答案 0 :(得分:1)
我坚信您没有使用正确的收藏夹。这适用于MongoDB 4.2。
创建索引:
db.location.createIndex({
startLocation: "2dsphere"
})
该馆藏的索引:
db.location.getIndexes()
[{
"v": 2,
"key": {
"_id": 1
},
"name": "_id_",
"ns": "stackoverflow.location"
}, {
"v": 2,
"key": {
"startLocation": "2dsphere"
},
"name": "startLocation_2dsphere",
"ns": "stackoverflow.location",
"2dsphereIndexVersion": 3
}
]
插入一些数据:
db.location.insert({
startLocation: {
type: "Point",
coordinates: [40, 5],
address: "Hellostreet 1",
description: "Hello"
}
})
汇总集合:
db.location.aggregate([{
$geoNear: {
near: {
type: 'Point',
coordinates: [41, 6]
},
distanceField: 'distance'
}
}
])
结果:
{
"_id" : ObjectId("5e404cdd13552bde0a0a9dc5"),
"startLocation" : {
"type" : "Point",
"coordinates" : [
40,
5
],
"address" : "Hellostreet 1",
"description" : "Hello"
},
"distance" : 157065.62445348964
}