На этой странице описано индексирование для Cloud Firestore. Cloud Firestore не создает индексы по умолчанию. Чтобы повысить производительность базы данных, создайте индексы для наиболее часто используемых запросов.
Индексы оказывают большое влияние на производительность базы данных. Если для запроса существует индекс, база данных может эффективно возвращать результаты, сокращая объем данных, которые необходимо сканировать, и сокращая работу, необходимую для сортировки результатов. Однако записи индекса увеличивают затраты на хранение и объем работы, выполняемой во время операции записи в индексированных полях.
Определение и структура индекса
Индекс состоит из следующих элементов:
- идентификатор подборки;
- список полей в заданной коллекции
- порядок сортировки (по возрастанию или по убыванию) для каждого поля.
Индекс также может включать параметры sparse, multikey или unique.
Порядок индекса
Порядок и направление сортировки каждого поля однозначно определяют индекс. Например, следующие индексы являются разными и не взаимозаменяемы:
| Коллекция | Поля |
|---|---|
| города | страна (по возрастанию), население (по убыванию) |
| города | население (по убыванию), страна (по возрастанию), |
При создании индекса для поддержки запроса включите поля в том же порядке, что и в запросе.
Плотность индекса
По умолчанию в записях индекса хранятся данные из всех документов в коллекции. Это называется неразреженным индексом. Запись в индексе будет добавлена для документа независимо от того, содержит ли он какие-либо поля, указанные в индексе. При создании записей индекса несуществующие поля обрабатываются как имеющие значение NULL. Чтобы изменить это поведение, вы можете определить индекс как разреженный.
Разреженные индексы
Разреженный индекс индексирует только те документы в коллекции, которые содержат значение (включая null) хотя бы для одного из индексированных полей. Разреженный индекс позволяет снизить расходы на хранение и повысить производительность.
Мультиключевые индексы для значений массивов.
Если вы создаете индекс для поля, содержащего значения массива, необходимо создать индекс с несколькими ключами. Обычный индекс не может индексировать значения массива. Мультиключевой индекс поддерживает до одного поля массива в определении индекса и может использоваться для операций, которые обходят значения массива.
Используйте мультиключевые индексы, только если вам нужно индексировать значения массивов. Обычные индексы имеют преимущества при обработке запроса. Например, обычные индексы могут более эффективно фильтровать значения в диапазоне.
Ошибки при работе со значениями массивов и мультиключевыми индексами возникают в следующих ситуациях:
- Операция пытается добавить значение массива в поле, индексированное обычным индексом. Чтобы добавить значение массива, необходимо удалить существующие обычные индексы в этом поле и заново создать их как мультиключевые.
- Вы пытаетесь создать обычный индекс для поля, содержащего значение массива. Вам нужно создать индекс с несколькими ключами или удалить значения массива.
- Операция пытается проиндексировать несколько полей со значениями массива. В мультиключевом индексе не может быть более одного поля со значением массива. Чтобы продолжить, измените модель данных или определения индексов.
- Вы пытаетесь создать мультиключевой индекс, в котором два пути к полям имеют общий префикс, например
users.postsиusers.zip.
Уникальные индексы
Установите параметр уникального индекса, чтобы обеспечить уникальные значения для индексированных полей. Для индексов по нескольким полям каждая комбинация значений должна быть уникальной в пределах индекса. База данных отклоняет любые операции обновления и вставки, которые пытаются создать записи индекса с повторяющимися значениями. Если данные индексируемых полей содержат повторяющиеся значения и вы попытаетесь создать уникальный индекс, то его создание завершится ошибкой, сообщение о которой появится в сведениях об операции.
Отсутствующие поля в уникальном индексе
Если вы вставите документ с отсутствующими полями для уникального индекса, индекс установит значения null для отсутствующих полей. Полученная запись индекса должна быть уникальной, иначе операция завершится ошибкой.
Например, для этого индекса:
db.cities.createIndex( { "name": 1 }, { unique: true } )
Если вы добавите в коллекцию документ {"abbreviation": "LA"}, уникальный индекс создаст запись, в которой для поля name будет задано значение null. Если вы попытаетесь добавить документ {"abbreviation": "NYC"}, операция не будет выполнена, поскольку результирующая запись для уникального индекса будет такой же.
То же самое относится к уникальным индексам с несколькими полями.
При создании или обновлении документа отсутствующие индексированные поля получают значение null, а полученная запись индекса должна быть уникальной в индексе.
Уникальные индексы для значений массива
Уникальный мультиключевой индекс можно использовать, чтобы в документах не было перекрывающихся элементов массива.
Этот тип индекса не требует, чтобы массив содержал уникальные значения в пределах одного документа.
Например, с уникальным индексом:
db.collection.createIndex( { "tags": 1 }, { unique: true } )
Допустимый документ для вставки:
{
"_id": 1,
"tags": [ "news", "tech", "news", "music" ]
}
Индекс допускает повторяющиеся значения ("news") в одном массиве одного документа.
Если вы попытаетесь вставить второй документ с повторяющимся элементом, операция завершится ошибкой:
{
"_id": 2,
"tags": [ "sports", "music" ]
}
Операция не выполняется, поскольку "music" уже присутствует в массиве документа 1 и сопоставлен в индексе.
Если вам нужно обеспечить уникальность элементов в одном массиве в одном документе, реализуйте это в логике приложения с помощью операторов обновления, таких как $addToSet вместо $push.
Пустые массивы, отсутствующие поля и нулевые значения
Обычно отсутствующие поля в уникальном индексе обрабатываются как null и должны быть уникальными для всех документов (см. раздел Отсутствующие поля в уникальном индексе).
Однако для уникальных индексов в полях массивов:
- Пустые массивы, отсутствующие поля и отдельные значения null. Если поле массива пустое, отсутствует или содержит отдельное значение
null(не внутри массива), ключи индекса для документа не генерируются. Поэтому несколько документов могут иметь пустые поля или отдельные значенияnull, не вызывая ошибок дублирования ключей. - Нулевые элементы в массиве. Если массив содержит элемент
со значением
null(например,["news", null]), то этотnullэлемент индексируется. Любой последующий документ, содержащий элементnullв поле индексированного массива, будет отклонен с ошибкой дублирования ключа.
Индексы TTL
Используйте индексы TTL, чтобы автоматически удалять устаревшие данные из баз данных. Индекс TTL определяет заданное поле как время истечения срока действия документов в заданной коллекции. С помощью TTL вы можете снизить затраты на хранение, удалив устаревшие данные. Обычно данные удаляются в течение 24 часов после истечения срока хранения.
Устранение ошибок при создании индекса
При управлении индексами могут возникать ошибки. Операция индексирования может завершиться ошибкой, если в базе данных возникнет проблема с данными. Операции индексирования могут завершаться ошибкой по следующим причинам:
- Достигнут лимит индекса. Например, возможно, достигнуто максимальное количество записей индекса на документ. Если создать индекс не удастся, вы увидите сообщение об ошибке. Если лимит не достигнут, повторите операцию индексирования.
- Требуется индекс с несколькими ключами. Хотя бы одно из индексированных полей содержит значение массива. Чтобы продолжить, используйте мультиключевой индекс или удалите значения массива.
- Операция пытается проиндексировать несколько полей со значениями массива. В мультиключевом индексе не может быть более одного поля со значением массива. Чтобы продолжить, измените модель данных или определения индексов.
- Вы установили параметр уникального индекса, и данные индексированных полей создадут повторяющиеся записи индекса. Чтобы продолжить, удалите повторяющиеся комбинации значений из данных.
Дальнейшие действия
- Узнайте, как создавать индексы и управлять ими или индексами TTL.