猫鼬无法识别我的2dsphere索引

时间:2020-02-09 17:16:06

标签: javascript node.js mongodb mongoose

我正在尝试为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);

1 个答案:

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