Как задать составной индекс в MongoDB через Ruby driver

Чтобы задать составной индекс в MongoDB через Ruby driver, используйте collection.indexes.create_one() и передайте несколько полей в нужном порядке. Составной индекс помогает запросам, которые фильтруют или сортируют данные сразу по нескольким полям

Пример:

collection.indexes.create_one({ user_id: 1, created_at: -1 })

Здесь индекс сначала идет по user_id по возрастанию, затем по created_at по убыванию

Полный пример

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")

Короткий чек-лист

  1. Определите частый запрос.
  2. Выберите порядок полей.
  3. Создайте индекс через create_one.
  4. Дайте индексу понятное имя.
  5. Проверьте список индексов.
  6. Проверьте запрос через план выполнения в MongoDB.

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Как проверить результат на практике

Для MongoDB-материала полезно делать три проверки: сначала выполнить команду на маленьком наборе тестовых документов, затем посмотреть результат через find() или MongoDB Compass, а после этого повторить действие на копии реальной структуры данных. Если запрос меняет документы, сначала запускайте его с фильтром на один документ и только потом расширяйте условие

Еще одна хорошая привычка — записывать исходное состояние и ожидаемый результат. Например: было три документа, после обновления изменился только один; был массив из пяти элементов, после операции остался нужный элемент; индекс появился в getIndexes(). Такая проверка быстро показывает, что вы исправили именно задачу, а не просто получили команду без ошибки

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x