Чтобы задать составной индекс в MongoDB через Ruby driver, используйте collection.indexes.create_one() и передайте несколько полей в нужном порядке. Составной индекс помогает запросам, которые фильтруют или сортируют данные сразу по нескольким полям
Пример:
collection.indexes.create_one({ user_id: 1, created_at: -1 })
Здесь индекс сначала идет по user_id по возрастанию, затем по created_at по убыванию
- Полный пример
- Почему порядок полей важен
- Уникальный составной индекс
- Проверить созданные индексы
- Частые ошибки
- Создали индекс не под тот запрос
- Перепутали порядок полей
- Поставили unique и получили ошибку
- Создали слишком много индексов
- Как проверить пользу индекса
- Короткий чек-лист
- Что почитать дальше по MongoDB
- Как проверить результат на практике
Полный пример
require "mongo"
client = Mongo::Client.new(["127.0.0.1:27017"], database: "shop")
collection = client[:orders]
collection.indexes.create_one(
{ user_id: 1, created_at: -1 },
name: "user_created_at_idx"
)
Такой индекс подойдет для запроса:
collection.find(user_id: 42).sort(created_at: -1)
MongoDB сможет быстро найти заказы пользователя и отдать их в нужном порядке
Почему порядок полей важен
Составной индекс работает слева направо. Индекс { user_id: 1, created_at: -1 } хорошо подходит для:
collection.find(user_id: 42)
collection.find(user_id: 42).sort(created_at: -1)
Но он хуже подходит для запроса только по created_at, потому что первое поле индекса — user_id
Уникальный составной индекс
Если нужно запретить повторы пары полей:
collection.indexes.create_one(
{ user_id: 1, external_id: 1 },
unique: true,
name: "uniq_user_external_id"
)
Так у одного пользователя не будет двух документов с одинаковым external_id
Проверить созданные индексы
collection.indexes.each do |index|
puts index.inspect
end
Также можно проверить в mongosh:
db.orders.getIndexes()
Частые ошибки
Создали индекс не под тот запрос
Сначала посмотрите, как реально выглядит запрос. Индекс должен поддерживать фильтр и сортировку, а не просто существовать
Перепутали порядок полей
Если чаще ищете по user_id, ставьте user_id первым. Если первое поле почти не используется в фильтре, польза индекса будет ниже
Поставили unique и получили ошибку
Уникальный индекс не создастся, если в коллекции уже есть повторяющиеся значения. Сначала найдите и исправьте такие документы
Создали слишком много индексов
Индексы ускоряют чтение, но замедляют запись и занимают место. Не добавляйте индексы без понятного запроса
Как проверить пользу индекса
После создания индекса проверьте запрос через план выполнения в mongosh:
db.orders.find({ user_id: 42 }).sort({ created_at: -1 }).explain("executionStats")
В Ruby driver сам индекс создается в приложении, но качество индекса удобнее проверять через MongoDB shell или профилирование запросов. Если запрос все равно просматривает слишком много документов, порядок полей в индексе может быть выбран неудачно
Если индекс больше не нужен, удаляйте его осторожно и только после проверки нагрузки:
collection.indexes.drop_one("user_created_at_idx")
Короткий чек-лист
- Определите частый запрос.
- Выберите порядок полей.
- Создайте индекс через
create_one. - Дайте индексу понятное имя.
- Проверьте список индексов.
- Проверьте запрос через план выполнения в MongoDB.
Что почитать дальше по MongoDB
Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:
- Discord bot на Python и MongoDB: как задать проверку
- Failed to start MongoDB database server: что проверить
- MongoDB Atlas: облачная база для первого проекта
- MongoDB Compass: подключение и первая коллекция без командной строки
Как проверить результат на практике
Для MongoDB-материала полезно делать три проверки: сначала выполнить команду на маленьком наборе тестовых документов, затем посмотреть результат через find() или MongoDB Compass, а после этого повторить действие на копии реальной структуры данных. Если запрос меняет документы, сначала запускайте его с фильтром на один документ и только потом расширяйте условие
Еще одна хорошая привычка — записывать исходное состояние и ожидаемый результат. Например: было три документа, после обновления изменился только один; был массив из пяти элементов, после операции остался нужный элемент; индекс появился в getIndexes(). Такая проверка быстро показывает, что вы исправили именно задачу, а не просто получили команду без ошибки



