Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Типы индексов в Cloud Firestore

Индексы - важный фактор производительности базы данных. Подобно индексу книги, который сопоставляет темы книги с номерами страниц, индекс базы данных сопоставляет элементы в базе данных с их местоположениями в базе данных. Когда вы отправляете базе данных запрос, база данных может использовать индекс для быстрого поиска местоположений запрошенных вами элементов.

На этой странице описаны два типа индексов , которые использует облако Firestore, индексы одного поля и сводных индексов .

Индекс за каждым запросом

Если для запроса не существует индекса, большинство баз данных просматривают свое содержимое построчно, это медленный процесс, который замедляется еще больше по мере роста базы данных. Облако Firestore гарантирует высокую производительность запросов с использованием индексов для всех запросов. В результате производительность запроса зависит от размера набора результатов, а не от количества элементов в базе данных.

Меньше управления индексами, больше разработки приложений

Cloud Firestore включает функции, которые сокращают время, необходимое для управления индексами. Индексы, необходимые для самых простых запросов, создаются автоматически. Как вы используете и протестировать приложение, Облако Firestore поможет вам определить и создать дополнительные индексы ваше приложение требует.

Типы индексов

Облако Firestore использует два типа индексов: одного поля и композит. Помимо количества проиндексированных полей, индексы с одним полем и составные индексы различаются по способу управления ими.

Индексы с одним полем

Индекс с одним полем хранит отсортированное отображение всех документов в коллекции, содержащих определенное поле. Каждая запись в индексе с одним полем записывает значение документа для определенного поля и расположение документа в базе данных. Cloud Firestore использует эти индексы для выполнения множества базовых запросов. Вы управляете индексами с одним полем, настраивая параметры автоматического индексирования вашей базы данных и исключения индекса.

Автоматическая индексация

По умолчанию Cloud Firestore автоматически поддерживает индексы с одним полем для каждого поля в документе и каждого подполя на карте. Cloud Firestore использует следующие настройки по умолчанию для индексов с одним полем:

  • Для каждого не-массива и , кроме карты области, Облако Firestore определяет две коллекции-Scope одного поля индексов, один в режиме восходящего и один в режиме убывания.

  • Для каждого поля карты Cloud Firestore создает один восходящий индекс области коллекции и один нисходящий индекс для каждого подполя на карте, не являющегося массивом и не связанного с картой.

  • Для каждого поля массива в документе Cloud Firestore создает и поддерживает индекс, содержащий массив в области коллекции.

  • Индексы с одним полем с областью действия группы сбора по умолчанию не поддерживаются.

Исключения для индексов одного поля

Вы можете освободить поле от вашей автоматической индексации установок пути создания освобождения индекса одностраничного поля. Исключение из индексации имеет приоритет над автоматическими настройками индекса для всей базы данных. Исключение может включить индекс с одним полем, который в противном случае ваши настройки автоматического индексирования отключили бы или отключили индекс с одним полем, который в противном случае включил бы автоматическое индексирование. В тех случаях , когда исключения могут быть полезными, см индексации лучших практиков .

Если вы создаете исключение индекса для одного поля для поля карты, подполя карты наследуют эти настройки. Однако вы можете определить исключения для индексов одного поля для определенных подполей. Если вы удалите исключение для подполя, подполе унаследует настройки исключения своего родителя, если они существуют, или настройки всей базы данных, если родительских исключений не существует.

Для создания и управления исключениями индекса одного поля, см Управления индексов в облаке Firestore .

Составные индексы

Составной индекс хранит отсортированное отображение всех документов в коллекции на основе упорядоченного списка полей для индексации.

Cloud Firestore использует составные индексы для поддержки запросов, которые еще не поддерживаются индексами с одним полем.

Cloud Firestore не создает автоматически составные индексы, как это делается для индексов с одним полем, из-за большого количества возможных комбинаций полей. Вместо этого, Облако Firestore помогает определить и создать необходимые составные индексы , как вы строите ваше приложение.

Если вы попытаетесь выполнить вышеуказанный запрос без предварительного создания необходимого индекса, Cloud Firestore вернет сообщение об ошибке, содержащее ссылку, по которой вы можете перейти, чтобы создать отсутствующий индекс. Это происходит каждый раз, когда вы пытаетесь выполнить запрос, не поддерживаемый индексом. Кроме того, можно определить и управлять композитными индексами вручную с помощью консоли или с помощью Firebase CLI . Более подробную информацию о создании и управлении составных индексов см Управление индексов .

Режимы индексации и области запросов

Вы настраиваете индексы с одним полем и составные индексы по-разному, но оба требуют, чтобы вы сконфигурировали режимы индекса и области запросов для ваших индексов.

Индексные режимы

При определении индекса вы выбираете режим индекса для каждого индексируемого поля. Режим индекса каждого поля поддерживает определенные условия запроса для этого поля. Вы можете выбрать один из следующих индексных режимов:

Индексный режим Описание
Возрастание Опоры < , <= , == , >= , > , и in пунктах запроса на поле и поддерживает сортировку результатов в порядке возрастания на основе этого значения поля.
По убыванию Опоры < , <= , == , >= , > , и in пунктах запроса на поле и поддерживает сортировку результатов в порядке на основе этого значения поля по убыванию.
Массив ‑ содержит Поддерживает array-contains и array-contains-any положение запроса на поле.

Области запроса

Каждый индекс ограничен коллекцией или группой коллекций. Это известно как область запроса индекса:

Объем коллекции
Cloud Firestore по умолчанию создает индексы с областью сбора. Эти индексы поддерживают запросы, возвращающие результаты из одной коллекции.

Объем группы коллекций
Группа коллекций включает в себя все коллекции с одинаковым идентификатором коллекции. Для выполнения запроса сбора группы , которая возвращает фильтрованную или заказанный результаты из коллекции группы, необходимо создать соответствующий индекс с коллекции группы области.

Пример индексации

Благодаря автоматическому созданию индексов с одним полем Cloud Firestore позволяет вашему приложению быстро поддерживать самые простые запросы к базе данных. Индексы отдельных полей позволяют выполнять простые запросы на основе значений полей и компараторы < , <= , == , >= , > , и in . Для полого массива, они позволяют выполнять array-contains и array-contains-any запросы.

Чтобы проиллюстрировать это, рассмотрите следующие примеры с точки зрения создания индекса. Следующий фрагмент кода создает несколько city документов в cities сбора и устанавливает name , state , country , capital , population , и tags полей для каждого документа:

Интернет
var citiesRef = db.collection("cities");

citiesRef.doc("SF").set({
    name: "San Francisco", state: "CA", country: "USA",
    capital: false, population: 860000,
    regions: ["west_coast", "norcal"] });
citiesRef.doc("LA").set({
    name: "Los Angeles", state: "CA", country: "USA",
    capital: false, population: 3900000,
    regions: ["west_coast", "socal"] });
citiesRef.doc("DC").set({
    name: "Washington, D.C.", state: null, country: "USA",
    capital: true, population: 680000,
    regions: ["east_coast"] });
citiesRef.doc("TOK").set({
    name: "Tokyo", state: null, country: "Japan",
    capital: true, population: 9000000,
    regions: ["kanto", "honshu"] });
citiesRef.doc("BJ").set({
    name: "Beijing", state: null, country: "China",
    capital: true, population: 21500000,
    regions: ["jingjinji", "hebei"] });

Принимая настройки автоматического индексирования по умолчанию, Cloud Firestore обновляет один восходящий однополевой индекс для каждого поля, не являющегося массивом, один убывающий однополевой индекс для любого поля, не являющегося массивом, и один индекс одиночного поля, содержащий массив, для поля массива. Каждая строка в следующей таблице представляет собой запись в индексе с одним полем:

Коллекция Поле проиндексировано Область запроса
города имя Коллекция
города состояние Коллекция
города страна Коллекция
города капитал Коллекция
города населения Коллекция
города имя Коллекция
города состояние Коллекция
города страна Коллекция
города капитал Коллекция
города населения Коллекция
города array-contains регионы Коллекция

Запросы, поддерживаемые индексами с одним полем

Используя эти автоматически созданные индексы с одним полем, вы можете выполнять простые запросы, подобные приведенным ниже:

Интернет
const stateQuery = citiesRef.where("state", "==", "CA");
const populationQuery = citiesRef.where("population", "<", 100000);
const nameQuery = citiesRef.where("name", ">=", "San Francisco");

Вы также можете создать in и соединение равенства ( == ) запросы:

Интернет
citiesRef.where('country', 'in', ["USA", "Japan", "China"])

// Compound equality queries
citiesRef.where("state", "==", "CO").where("name", "==", "Denver")
citiesRef.where("country", "==", "USA")
         .where("capital", "==", false)
         .where("state", "==", "CA")
         .where("population", "==", 860000)

Если вам необходимо выполнить соединение запроса, использующего сравнение диапазона ( < , <= , > или >= ) , или если вам нужно отсортировать по другому полю, необходимо создать составной индекс для этого запроса.

array-contains индекс позволяет запросить regions поле массива:

Интернет
citiesRef.where("regions", "array-contains", "west_coast")
// array-contains-any and array-contains use the same indexes
citiesRef.where("regions", "array-contains-any", ["west_coast", "east_coast"])

Запросы, поддерживаемые составными индексами

Cloud Firestore использует составные индексы для поддержки составных запросов, которые еще не поддерживаются индексами с одним полем. Например, вам понадобится составной индекс для следующих запросов:

Интернет
citiesRef.where("country", "==", "USA").orderBy("population", "asc")
citiesRef.where("country", "==", "USA").where("population", "<", 3800000)
citiesRef.where("country", "==", "USA").where("population", ">", 690000)
// in and == clauses use the same index
citiesRef.where("country", "in", ["USA", "Japan", "China"])
         .where("population", ">", 690000)

Для этих запросов требуется составной индекс, указанный ниже. Поскольку в запросе используется равенство ( == или in ) для country области, вы можете использовать режим индекса по возрастанию или убыванию в этой области. По умолчанию в предложениях неравенства применяется возрастающий порядок сортировки на основе поля в предложении неравенства.

Коллекция Поля проиндексированы Область запроса
города (или ) страна, население Коллекция

Для выполнения тех же запросов , но с нисходящим порядком сортировки, вам нужен дополнительный композитный индекс в нисходящем направлении для population :

Интернет
citiesRef.where("country", "==", "USA").orderBy("population", "desc")

citiesRef.where("country", "==", "USA")
         .where("population", "<", 3800000)
         .orderBy("population", "desc")

citiesRef.where("country", "==", "USA")
         .where("population", ">", 690000)
         .orderBy("population", "desc")

citiesRef.where("country", "in", ["USA", "Japan", "China"])
         .where("population", ">", 690000)
         .orderBy("population", "desc")
Коллекция Поля проиндексированы Область запроса
города страна, население Коллекция
города страна, население Коллекция

Кроме того, необходимо создать составной индекс совместить array-contains или array-contains-any запрос , с дополнительными пунктами.

Интернет
citiesRef.where("regions", "array-contains", "east_coast")
         .where("capital", "==", true)

// array-contains-any and array-contains use the same index
citiesRef.where("regions", "array-contains-any", ["west_coast", "east_coast"])
         .where("capital", "==", true)
Коллекция Поля проиндексированы Область запроса
города массив содержит тег, (или ) капитал Коллекция

Запросы, поддерживаемые индексами группы сбора

Чтобы продемонстрировать индекс с коллекцией группы масштабом, представьте , что вы добавить landmarks суб-коллекцию в некоторые city документах:

Интернет
var citiesRef = db.collection("cities");

citiesRef.doc("SF").collection("landmarks").doc().set({
    name: "Golden Gate Bridge",
    category : "bridge" });
citiesRef.doc("SF").collection("landmarks").doc().set({
    name: "Golden Gate Park",
    category : "park" });

citiesRef.doc("DC").collection("landmarks").doc().set({
    name: "National Gallery of Art",
    category : "museum" });
citiesRef.doc("DC").collection("landmarks").doc().set({
    name: "National Mall",
    category : "park" });

Используя следующий индекс одного поля с коллекцией объема, вы можете запросить одного города в landmarks коллекции на основе category области:

Коллекция Поля проиндексированы Область запроса
ориентиры (или ) категории Коллекция
Интернет
citiesRef.doc("SF").collection("landmarks").where("category", "==", "park")
citiesRef.doc("SF").collection("landmarks").where("category", "in", ["park", "museum"])

А теперь представьте, что вам интересно узнать о достопримечательностях всех городов. Для выполнения этого запроса на сбор группы , состоящей из всех landmarks коллекции, вы должны включить landmarks индекса одного поля с коллекцией группы сферой:

Коллекция Поля проиндексированы Область запроса
ориентиры (или ) категории Коллекционная группа

При включении этот показатель, вы можете запросить landmarks группы коллекции:

Интернет
var landmarksGroupRef = db.collectionGroup("landmarks");

landmarksGroupRef.where("category", "==", "park")
landmarksGroupRef.where("category", "in", ["park", "museum"])

Чтобы выполнить запрос группы сбора, который возвращает отфильтрованные или упорядоченные результаты, необходимо включить соответствующий индекс с одним полем или составной индекс с областью действия группы сбора. Однако запросы группы сбора, которые не фильтруют и не упорядочивают результаты, не требуют дополнительных определений индекса.

Например, вы можете выполнить следующий запрос группы сбора без включения дополнительного индекса:

Интернет
db.collectionGroup("landmarks").get()

Записи указателя

Сконфигурированные показатели вашего проекта, а также структура документа, как влияют на запись индекса для документа, который в конечном счете засчитан ввод индекса лимит счета .

Вот пример для иллюстрации.

Документ

name : "San Francisco"
temperatures : {summer: 67, winter: 55}
neighborhoods : ["Mission", "Downtown", "Marina"]

Индексы с одним полем

  • (Автоматически) имя ASC и DESC
  • (Автоматически) температуры ASC и DESC
  • (Автоматически) Массив окрестностей содержит

Составные индексы

  • название ASC, районы ASC
  • название DESC, окрестности ASC

Результирующие записи индекса

Эта конфигурация индексации приводит к появлению следующих 12 записей индекса для документа:

Показатель Вход
имя ASC & DESC название: "Сан-Франциско"
температуры ASC и DESC температура. летом: 67
температуры ASC и DESC температура. зимой: 55
окрестности Массив содержит кварталы: «Миссия»
окрестности Массив содержит кварталы: «Центр города»
окрестности Массив содержит микрорайоны: «Марина»
название ASC, районы ASC название: «Сан-Франциско», кварталы: «Миссия»
название ASC, районы ASC название: "Сан-Франциско", кварталы: "Центр города"
название ASC, районы ASC название: «Сан-Франциско», кварталы: «Марина»
название DESC, окрестности ASC название: «Сан-Франциско», кварталы: «Миссия»
название DESC, окрестности ASC название: "Сан-Франциско", кварталы: "Центр города"
название DESC, окрестности ASC название: «Сан-Франциско», кварталы: «Марина»

Индексы и цены

Индексы вносят вклад в стоимость хранения вашего приложения. Более подробную информацию о том , как рассчитывается размер для хранения индексов, см Индекс размера входа .

Использование слияния индексов

Хотя Cloud Firestore использует индекс для каждого запроса, он не обязательно требует одного индекса для каждого запроса. Для запросов с несколькими равенства ( == ) положений и, возможно, в orderBy пункте, Облако Firestore может повторно использовать существующие индексы. Cloud Firestore может объединять индексы для простых фильтров равенства для создания составных индексов, необходимых для более крупных запросов на равенство.

Вы можете снизить затраты на индексирование, определив ситуации, в которых вы можете воспользоваться слиянием индексов. Например, представьте себе restaurants коллекцию для рейтинга ресторана приложения:

  • рестораны

    • burgerthyme

      name : "Burger Thyme"
      category : "burgers"
      city : "San Francisco"
      editors_pick : true
      star_rating : 4

Теперь представьте, что это приложение использует запросы, подобные приведенным ниже. Обратите внимание , что приложение использует комбинацию положений равенства для category , city и editors_pick всегда при сортировке по возрастанию star_rating :

Интернет
db.collection("restaurants").where("category", "==", "burgers")
                            .orderBy("star_rating")

db.collection("restaurants").where("city", "==", "San Francisco")
                            .orderBy("star_rating")

db.collection("restaurants").where("category", "==", "burgers")
                            .where("city", "==", "San Francisco")
                            .orderBy("star_rating")

db.collection("restaurants").where("category", "==", "burgers")
                            .where("city", "==" "San Francisco")
                            .where("editors_pick", "==", true )
                            .orderBy("star_rating")

Вы можете создать индекс для каждого запроса:

Коллекция Поля проиндексированы Область запроса
рестораны категория, star_rating Коллекция
рестораны город, star_rating Коллекция
рестораны категория, город, star_rating Коллекция
рестораны категория, город, editors_pick, star_rating Коллекция

В качестве лучшего решения вы можете уменьшить количество индексов, воспользовавшись возможностью Cloud Firestore объединять индексы для предложений равенства:

Коллекция Поля проиндексированы Область запроса
рестораны категория, star_rating Коллекция
рестораны город, star_rating Коллекция
рестораны editors_pick, star_rating Коллекция

Этот набор индексов не только меньше, он также поддерживает дополнительный запрос:

Интернет
db.collection("restaurants").where("editors_pick", "==", true)
                            .orderBy("star_rating")

Пределы индексации

К индексам применяются следующие ограничения. Для всех квот и ограничений, см квоты и лимиты .

Предел Подробности
Максимальное количество составных индексов для базы данных 200
Максимальное количество исключений для индекса с одним полем для базы данных 200

Максимальное количество записей указателя для каждого документа

40 000

Количество записей указателя складывается из следующих значений для документа:

  • Количество записей указателя с одним полем
  • Количество записей составного индекса

Чтобы увидеть , как облако Firestore получается документ и набор индексов в индексные записи, см этого показателя счетчик начального пример .

Максимальный размер записи индекса

7,5 КБ

Чтобы увидеть , как облако Firestore вычисляет индекс размера входа, см размера начального индекса .

Максимальная сумма размеров элементов указателя документа

8 МБ

Общий размер - это сумма следующего для документа:

  • Сумма размера записей индекса документа с одним полем.
  • Сумма размеров записей составного индекса документа.
  • Максимальный размер значения индексированного поля

    1500 байт

    Значения полей размером более 1500 байт усекаются. Запросы с усеченными значениями полей могут возвращать противоречивые результаты.

    Лучшие практики индексирования

    Для большинства приложений вы можете полагаться на автоматическое индексирование и ссылки в сообщениях об ошибках для управления своими индексами. Однако вы можете добавить исключения для одного поля в следующих случаях:

    Случай Описание
    Большие строковые поля

    Если у вас есть строковое поле, которое часто содержит длинные строковые значения, которые вы не используете для запросов, вы можете сократить расходы на хранение, исключив это поле из индексации.

    Высокая скорость записи в коллекцию, содержащую документы с последовательными значениями

    Если вы индексируете поле, которое последовательно увеличивается или уменьшается между документами в коллекции, например, отметка времени, то максимальная скорость записи в коллекцию составляет 500 операций записи в секунду. Если вы не запрашиваете на основе поля с последовательными значениями, вы можете исключить поле из индексации, чтобы обойти это ограничение.

    Например, в случае использования Интернета вещей с высокой скоростью записи коллекция, содержащая документы с полем отметки времени, может приближаться к пределу 500 операций записи в секунду.

    Большой массив или поля карты

    Поля большого массива или карты могут приближаться к пределу в 40 000 записей индекса на документ. Если вы не выполняете запросы на основе большого массива или поля карты, вы должны освободить его от индексации.