MongoDB
Как понять причину поведения выборки в MongoDB
Чтобы понять, почему выборка в MongoDB работает не так, начните с четырех проверок: фильтр, типы данных, сортировка и план выполнения через explain(). В большинстве случаев проблема оказывается не в MongoDB, а в том, что поле хранится другим типом, запрос не попадает в индекс, сортировка меняет порядок или фильтр написан не под реальную структуру документа
Пример диагностики:
db.products.find({ price: { $gte: 1000 } }).explain("executionStats")
executionStats покажет, сколько документов MongoDB просмотрела и использовала ли индекс
Проверьте реальную структуру документа
Сначала посмотрите один документ:
db.products.findOne()
Частая ошибка: в коде вы ищете price, а в части документов поле называется cost. Или ожидаете число, а в базе лежит строка
Плохо:
{ price: "1200" }
Хорошо:
{ price: 1200 }
Запрос { price: { $gte: 1000 } } для строк и чисел будет вести себя не так, как ожидает новичок
Проверьте фильтр
Если запрос не возвращает данные, упростите его:
db.products.find({})
db.products.find({ category: "books" })
db.products.find({ category: "books", inStock: true })
Добавляйте условия по одному. Так проще увидеть, какое условие отсекает документы
Проверьте сортировку
Если документы есть, но порядок странный, проверьте sort():
db.products.find({}).sort({ price: -1 })
Если price строка, сортировка будет лексикографической, а не числовой. Это одна из самых неприятных ошибок в учебных проектах
Проверьте индекс через explain
db.products.find({ category: "books" }).explain("executionStats")
Смотрите на два признака:
- использует ли запрос индекс;
- сколько документов просмотрено.
Если коллекция большая, а MongoDB просматривает почти все документы, нужен индекс:
db.products.createIndex({ category: 1 })
После этого снова запустите explain() и сравните количество просмотренных документов. Если число стало заметно меньше, индекс действительно помогает запросу, а не просто существует в коллекции
Проверьте регистр и collation
MongoDB по умолчанию чувствительна к регистру в строках. Book и book — разные значения
Если нужно искать без учета регистра, можно использовать collation или регулярное выражение, но подход выбирают под задачу и индексы
Частые причины странной выборки
Поле называется не так, как в запросе
Тип данных отличается: строка вместо числа, строка вместо даты, ObjectId вместо строки
Запрос ищет вложенное поле не тем путем
Сортировка применяется после фильтра и меняет видимый порядок
Индекс не используется, поэтому запрос медленный
Регистр строк отличается
Короткий чек-лист
- Посмотреть
findOne(). - Упростить фильтр до минимума.
- Проверить типы данных.
- Проверить путь к вложенному полю.
- Проверить
sort(). - Запустить
explain("executionStats"). - Добавить или исправить индекс.
Что почитать дальше по MongoDB
Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:
- Как расшифровать лог MongoDB и понять причину ошибки
- Discord bot на Python и MongoDB: как задать проверку
- Failed to start MongoDB database server: что проверить
- MongoDB Atlas: облачная база для первого проекта
Как проверить результат на практике
Для MongoDB-материала полезно делать три проверки: сначала выполнить команду на маленьком наборе тестовых документов, затем посмотреть результат через find() или MongoDB Compass, а после этого повторить действие на копии реальной структуры данных. Если запрос меняет документы, сначала запускайте его с фильтром на один документ и только потом расширяйте условие
Еще одна хорошая привычка — записывать исходное состояние и ожидаемый результат. Например: было три документа, после обновления изменился только один; был массив из пяти элементов, после операции остался нужный элемент; индекс появился в getIndexes(). Такая проверка быстро показывает, что вы исправили именно задачу, а не просто получили команду без ошибки