Пн goose не может распознать мой 2dsphere индекс - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь добавить 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
    }
  });
});

также с маршрутизатора, вы можете увидеть, как я отправьте запрос URL ниже

tourRouter.route('/distances/:latlng/unit/:unit').get(tourController.getDistances);

1 Ответ

1 голос
/ 09 февраля 2020

Я твердо верю, что вы не используете надлежащую коллекцию. Это работает для 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...