Почему мой запрос агрегации MongoDB такой медленный

#database #mongodb #mongoose #indexing

#База данных #mongodb #мангуст #индексирование

Вопрос:

У меня есть несколько идентификаторов (обычно 2 или 3) пользователей, которых мне нужно извлечь из базы данных. Дело в том, что мне также нужно знать расстояние от определенной точки. Проблема в том, что в моей коллекции 1 000 000 документов (пользователей), и для извлечения пользователей требуется более 30 секунд.

Почему это происходит? Когда я просто использую $in оператор для _id , он работает нормально и возвращает все менее чем за 200 мс, и когда я просто использую $geoNear оператор, он также работает нормально, но когда я использую 2 вместе, все безумно замедляется. Что мне делать? Опять же, все, что мне нужно, это несколько пользователей с идентификаторами из userIds массива и их расстоянием от определенной точки ( user.location ) .

РЕДАКТИРОВАТЬ: Также хотел упомянуть, что когда я использую $nin вместо $in запроса, он также выполняет pefrectly. $in Проблема возникает только в сочетании с $geoNear

 const user = await User.findById('logged in users id');
const userIds = ['id1', 'id2', 'id3'];

[
    {
        $geoNear: {
            near: user.location,
            distanceField: 'distance',
            query: {
                _id: { $in: userIds }
            }
        }
    }
]
 

Комментарии:

1. У вас случайно нет каких-либо индексов в ID или геопространственных полях?

2. Если вы запустите db.coll.explain().aggregate(yourPipeline) , вы, вероятно, обнаружите, что он не использует _id индекс (только 2dIndex). И вы не можете выполнить сопоставление, потому что это должен быть первый этап. Вы можете попытаться обойти его только с помощью какого-либо другого оператора. Кроме того, я подозреваю, что если вы добавите {$project:{geolocationField:1}} , он будет работать быстрее, но вы должны протестировать и idk, насколько бесполезным это станет.

3. @AliDowair запрос не будет выполняться без геопространственного индекса

4. Местоположение действительно имеет индекс 2dsphere. Я попробую ваше предложение

Ответ №1:

Я нашел обходной путь: я просто запрашиваю по полю ID, а позже использую библиотеку для определения расстояния возвращенных документов от центральной точки.

Ответ №2:

Индексация ваших данных может быть решением вашей проблемы. без индексации mongodb должен сканировать все документы.

Комментарии:

1. У меня есть индекс как для поля ID, так и для поля location. Вот почему я был в замешательстве, учитывая, что оба они проиндексированы, почему это занимает так много времени? В любом случае я нашел обходной путь, как указано в моем ответе. В любом случае спасибо за ввод