Задать вопрос
@froosty

Как можно оптимизировать сортировку в запросе к MongoDB?

Доброго времени суток. Возникла проблема со скоростью выполнения запроса к MongoDB. Запрос выглядит следующим образом:
mongoose.model('mail')
.find({
        $or: [
                {sender: user_id, recipient: owner_id, mType: 0, deleted: false},
                {sender: owner_id, recipient: user_id, mType: 1, deleted: false, read: {$ne: 4}, action: {$ne: 'some_type'}}
        ]
})
.populate('sender', 'nickname photos.1 birth online status role')
.populate('recipient', 'nickname photos.1 birth online status')
.sort({date: -1})
.skip((page - 1) * mailsPerPage)
.limit(mailsPerPage)


Сортировка в запросе оч. сильно увеличивает время его отработки. Подскажите, каким образом можно запрос оптимизировать, чтобы сортировка отрабатывала быстрее?
  • Вопрос задан
  • 496 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@lega
По хорошему фильтр и сортировка должны соответствовать индексу.

Если нужна максимальная скорость то нужно упростить запрос, избавится от $or и доп. условий, например сделать так:
1) в документ сохранять готовое значение sender+recipient которое проходит условие, например: { _search1: {user_id1: user_id1, user_id2: user_id2} } (записать ид пользователей в порядке нарастания), заполнять этот массив если выполняются условия с mType, deleted, read, action.
2) Сделать индекс: db.mail.ensureIndex({_search1: 1, "date" : -1 })
В итоге запрос выдаст результат быстро и с учетом всех условий:
collection.find({ _search:{user_id1: user_id1, user_id2: user_id2} }).sort({date: -1})

Если сортировать идентификаторы не хочется, то можно сделать массивом:
{ _search:[sender, recipient] }, и запрос
collection.find({ _search:{$all: [sender, recipient]} }).sort({date: -1})
, для этого случая возможно лучше будет такой индекс: db.mail.ensureIndex({ "date" : -1, _search1: 1 })
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
dizballanze
@dizballanze
Software developer at Yandex
Индекс проставьте на поле по которому сортировка:
db.mail.ensureIndex( { "date" : -1 } )

Обратите внимание, что индекс должен такую же сортировку иметь, т.е. если в вашем примере по-убыванию (-1), то и индекс должен быть по-убыванию.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы