インデックスの概要

インデックスは、データベースのパフォーマンスにおける重要な要素です。書籍内のトピックをページ番号に対応付ける書籍の索引(インデックス)と同様に、データベースのインデックスはデータベース内のアイテムをデータベース内の場所にマッピングします。データベースに対してクエリを実行すると、データベースはインデックスを使用して、リクエストされたアイテムの場所をすばやく特定できます。

このページでは、Firestore で使用される、単一フィールド インデックス複合インデックスの 2 種類のインデックスについて説明します。

インデックスの定義と構造

インデックスは、フィールドごとに対応するインデックス モードで、特定のドキュメントのフィールドのリストに対して定義されます。

インデックスには、インデックスの定義で指定したすべてのフィールドのエントリが含まれます。インデックスには、インデックスに基づくクエリの予想結果であるすべてのドキュメントが含まれます。ドキュメントがインデックスに含まれるのは、インデックスで使用されているすべてのフィールドのインデックスに登録された設定値がある場合のみです。インデックス定義で、ドキュメントに設定値がないフィールドを参照している場合、そのドキュメントはインデックスに表示されません。この場合、そのドキュメントがインデックスに基づくクエリの結果として返されることはありません。

複合インデックスは、インデックス定義で指定された順序で、フィールド値で並べ替えられます。

すべてのクエリの背後にインデックスが存在

クエリを実行する際にインデックスが存在しないと、ほとんどのデータベースはアイテムごとにデータベース内のコンテンツ全体をクロールすることになるため、データベースが大きくなるにつれて処理がますます遅くなります。Firestore では、すべてのクエリに対してインデックスを使用することで、クエリの高パフォーマンスを確保します。したがって、クエリのパフォーマンスはデータベース内のアイテム数ではなく、結果セットのサイズによって左右されます。

インデックス管理の手間を減らし、アプリ開発により注力する

Firestore には、インデックス管理にかかる時間を短縮できる機能があります。最も基本的なクエリに必要なインデックスは、自動的に作成されます。アプリを使用してテストする際に、Firestore はアプリで必要となる追加のインデックスを識別して作成できるようにします。

インデックスのタイプ

Firestore では、単一フィールド インデックスと複合インデックスという 2 種類のインデックスを使用します。単一フィールド インデックスと複合インデックスでは、インデックス登録されるフィールドの数が違うだけでなく、管理方法も異なります。

単一フィールド インデックス

単一フィールド インデックスは、特定の 1 つのフィールドを含む、コレクション内のすべてのドキュメントの並べ替え済みマッピングを保持します。単一フィールド インデックスの各エントリには、ドキュメント内の特定のフィールドの値と、そのドキュメントのデータベース内での位置が記録されます。Firestore はこうしたインデックスを使用して、多くの基本的なクエリを実行します。単一フィールド インデックスを管理するには、データベースの自動インデックスの設定とインデックス除外を構成します。

自動インデックス

デフォルトでは、Firestore はドキュメント内のフィールドおよびマップ内のサブフィールドごとに単一フィールド インデックスを自動的に維持します。Firestore は、単一フィールド インデックスに次のデフォルト設定を使用します。

  • 配列でもなくマップでもないフィールドに対しては、コレクションのスコープを使用する 2 つの単一フィールド インデックス(1 つは昇順モード、もう 1 つは降順モード)が定義されます。

  • Firestore は、マップ フィールドごとに以下を作成します。

    • 配列でもマップでもないサブフィールドごとに、コレクションのスコープを使用する 1 つの昇順インデックス。
    • 配列でもマップでもないサブフィールドごとに、コレクションのスコープを使用する 1 つの降順インデックス。
    • 配列サブフィールドごとにコレクションのスコープを使用する 1 つの配列の内容インデックス。
    • Firestore は、各マップのサブフィールドを再帰的にインデックス登録します。
  • ドキュメント内の配列フィールドに対しては、コレクションのスコープ配列の内容インデックスが作成されて維持されます。

  • スコープがコレクション グループに設定された単一フィールド インデックスは、デフォルトでは維持されません。

単一フィールド インデックス除外

単一フィールド インデックス除外を作成することで、自動インデックス設定からフィールドを除外できます。インデックス除外は、データベース全体の自動インデックス設定より優先されます。除外すると、自動インデックス設定によって本来は無効になる単一フィールド インデックスを有効にしたり、自動インデックスによって本来は有効になる単一フィールド インデックスを無効にできます。除外が役立つケースについては、インデックスに関するベスト プラクティスをご覧ください。

* フィールドのパス値を使用して、コレクション グループ内のすべてのフィールドにコレクション レベルのインデックス除外を追加します。たとえば、コレクション グループ comments の場合、comments コレクション グループのすべてのフィールドと一致するようにフィールドパスを * に設定して、コレクション グループ内のすべてのフィールドのインデックス登録を無効にします。その後、除外を追加して、クエリに必要なフィールドのみをインデックスに登録できます。インデックス フィールドの数を減らすと、ストレージ コストが削減され、書き込みパフォーマンスが向上します。

マップ フィールドの単一フィールド インデックス除外を作成すると、マップのサブフィールドはそれらの設定を継承します。ただし、特定のサブフィールドに対して単一フィールド インデックス除外を定義することはできます。サブフィールドの除外を削除すると、サブフィールドはその親の除外設定が存在する場合はそれを継承し、親の除外が存在しない場合はデータベース全体の設定を継承します。

単一フィールド インデックス除外を作成および管理する方法については、インデックスの管理をご覧ください。

複合インデックス

複合インデックスには、インデックスを作成するフィールドの順序付きリストに基づいて並べ替えられた、コレクション内のすべてのドキュメントのマッピングが格納されます。

Firestore は複合インデックスを使用して、単一フィールド インデックスではサポートされないクエリをサポートします。

Firestore では、可能なフィールドの組み合わせの数が多くなるため、単一フィールド インデックスの場合とは異なり、複合インデックスの自動作成は行いません。代わりに、Firestore は、アプリを作成する際に必要な複合インデックスを特定して作成できるようにします。

インデックスでサポートされていないクエリを試行するたびに、Firestore は、不足しているインデックスを作成するためのリンクを含むエラー メッセージを返します。

また、コンソールまたは Firebase CLI で複合インデックスを手動で定義して管理することもできます。複合インデックスの作成と管理の詳細については、インデックスの管理をご覧ください。

インデックス モードとクエリのスコープ

単一フィールド インデックスと複合インデックスの構成方法は異なりますが、どちらもインデックス モードとインデックスのクエリのスコープを構成する必要があります。

インデックス モード

インデックスを定義するときは、インデックスを作成するフィールドごとにインデックス モードを選択します。各フィールドのインデックス モードでは、そのフィールドに対する特定のクエリ句がサポートされます。次のインデックス モードから選択できます。

インデックス モード 説明
昇順 フィールドでの <<===>=>!=innot-in の各クエリ句の使用と、そのフィールド値に基づいた結果の並べ替え(昇順)がサポートされます。
降順 フィールドでの <<===>=>!=innot-in の各クエリ句の使用と、そのフィールド値に基づいた結果の並べ替え(降順)がサポートされます。
配列の内容 フィールドでの array-contains クエリ句と array-contains-any クエリ句の使用がサポートされます。
Vector フィールドでの FindNearest クエリ句の使用がサポートされます。

クエリのスコープ

各インデックスは、コレクションまたはコレクション グループのいずれかをスコープとします。これはインデックスのクエリのスコープと呼ばれます。

コレクションのスコープ
Firestore はデフォルトで、スコープをコレクションに設定したインデックスを作成します。こうしたインデックスでは、単一のコレクションから結果を返すクエリがサポートされます。

コレクション グループのスコープ
コレクション グループには、同じコレクション ID があるすべてのコレクションが含まれます。コレクション グループからフィルタ処理された結果、もしくは並べ替えられた結果を返すコレクション グループ クエリを実行するには、コレクション グループのスコープに対応するインデックスを作成する必要があります。

デフォルトの順序と __name__ フィールド

インデックスでは、各フィールドに指定されたインデックス モード(昇順または降順)によるドキュメントの並べ替えに加え、各ドキュメントの __name__ フィールドによる最終的な並べ替えが適用されます。__name__ フィールドの値は、ドキュメントの完全なパスに設定されます。つまり、同じフィールド値を持つ結果セット内のドキュメントは、ドキュメント パスで並べ替えられます。

デフォルトでは、__name__ フィールドはインデックス定義で最後に並べ替えられたフィールドと同じ方向に並べ替えられます。次に例を示します。

コレクション インデックス登録されるフィールド クエリのスコープ
cities name, __name__ コレクション
cities state, __name__ コレクション
cities country, population, __name__ コレクション

デフォルト以外の __name__ 方向で結果を並べ替えるには、そのインデックスを作成する必要があります。

インデックスのプロパティ

クエリを最も効率的に実行できるインデックスは、以下のプロパティで定義されます。

  • 等式フィルタで使用されるフィールド
  • 並べ替え順序で使用されるフィールド
  • 範囲フィルタと不等式フィルタで使用されるフィールド(並べ替え順序にまだ含まれていないもの)
  • 集計で使用されるフィールド(並べ替え順序、範囲フィルタと不等式フィルタにまだ含まれていないもの)

Firestore では、クエリの結果を次のように計算します。

  1. クエリのコレクション、フィルタのプロパティ、フィルタの演算子、並べ替え順序に対応するインデックスを特定します。
  2. スキャンが開始されるインデックス位置を特定します。開始位置にはクエリの等式フィルタが、終了位置には最初の orderBy フィールドの範囲フィルタと不等式フィルタが付いています。
  3. インデックスのスキャンを開始して、スキャン プロセスが次のいずれかを達成するまで、すべてのフィルタを満たす各ドキュメントを返します。
    • フィルタ条件を満たさないドキュメントを検出し、後続のドキュメントがフィルタ条件を満たさないことを確認した。
    • インデックスの末尾に到達した。
    • クエリでリクエストされた結果の最大数に達した。

インデックス登録の例

Firestore は単一フィールド インデックスを自動的に作成するため、アプリケーションでは最も基本的なデータベース クエリをすぐにサポートできます。単一フィールド インデックスを使用すると、フィールドの値と比較演算子 <<===>=>in に基づく単純なクエリを実行できます。配列フィールドについては array-contains クエリと array-contains-any クエリを実行できます。

たとえば、次の例をインデックス作成の観点から確認します。次のスニペットでは、cities コレクションにいくつかの city ドキュメントを作成し、各ドキュメントの namestatecountrycapitalpopulationtags フィールドを設定します。

ウェブ
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"] });

デフォルトの自動インデックス設定の場合、Firestore は、配列以外のフィールドごとの 1 つの昇順単一フィールド インデックスと、配列以外のフィールドごとの 1 つの降順単一フィールド インデックスを更新します。配列フィールドについては、1 つの配列の内容の単一フィールド インデックスを更新します。次の表の各行は、単一フィールド インデックスのエントリを表しています。

コレクション インデックス登録されるフィールド クエリのスコープ
cities name コレクション
cities state コレクション
cities country コレクション
cities capital コレクション
cities population コレクション
cities name コレクション
cities state コレクション
cities country コレクション
cities capital コレクション
cities population コレクション
cities array-contains regions コレクション

単一フィールド インデックスでサポートされるクエリ

自動的に作成されるこれらの単一フィールド インデックスを使用すると、次のようなシンプルなクエリを実行できます。

ウェブ
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"])

複合インデックスでサポートされるクエリ

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)

これらのクエリには、以下に示す複合インデックスが必要です。クエリでは country フィールドに対して等式(== または in)を使用しているため、このフィールドのインデックス モードは降順と昇順のどちらでもかまいません。デフォルトでは、不等式句は、その不等式句のフィールドに基づいて昇順の並べ替えを適用します。

コレクション インデックス登録されるフィールド クエリのスコープ
cities (or ) country, population コレクション

同じクエリを実行するけれども並べ替えが降順の場合は、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")
コレクション インデックス登録されるフィールド クエリのスコープ
cities country, population コレクション
cities country, population コレクション

インデックス マージによるパフォーマンスの低下を回避するには、複合インデックスを作成して、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)
コレクション インデックス登録されるフィールド クエリのスコープ
cities array-contains tags, (or ) capital コレクション

コレクション グループ インデックスが対応しているクエリ

コレクション グループのスコープがあるインデックスを示すために、いくつかの city ドキュメントに landmarks サブコレクションを追加します。

ウェブ
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" });

次のコレクションのスコープの単一フィールド インデックスを使用すると、category フィールドに基づいて単一の都市の landmarks コレクションに対してクエリを実行できます。

コレクション インデックス登録されるフィールド クエリのスコープ
landmarks (or ) category コレクション
ウェブ
citiesRef.doc("SF").collection("landmarks").where("category", "==", "park")
citiesRef.doc("SF").collection("landmarks").where("category", "in", ["park", "museum"])

たとえば、クエリですべての都市でのランドマークを調べる場合、すべての landmarks コレクションで構成されるコレクション グループに対してこのクエリを実行します。また、コレクション グループのスコープがある landmarks 単一フィールド インデックスを有効にする必要もあります。

コレクション インデックス登録されるフィールド クエリのスコープ
landmarks (or ) category コレクション グループ

このインデックスを有効にすると、landmarks コレクション グループに対してクエリを実行できます。

ウェブ
var landmarksGroupRef = db.collectionGroup("landmarks");

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

フィルタ処理された結果、もしくは並べ替えられた結果を返すコレクション グループ クエリを実行するには、コレクション グループのスコープに対応する単一フィールド インデックスまたは複合インデックスを有効にする必要があります。ただし、結果のフィルタ処理や並べ替えを行わないコレクション グループ クエリでは、追加のインデックス定義は必要ありません。

たとえば、追加のインデックスを有効にせずに次のコレクション グループ クエリを実行できます。

ウェブ
db.collectionGroup("landmarks").get()

インデックス エントリ

プロジェクトの構成済みインデックスとドキュメントの構造が、ドキュメントのインデックス エントリの数を左右します。インデックス エントリは、インデックス エントリ数の上限にカウントされます。

次の例は、ドキュメントのインデックス エントリを示しています。

ドキュメント

/cities/SF

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

単一フィールド インデックス

  • city_name 昇順
  • city_name 降順
  • temperatures.summer 昇順
  • temperatures.summer 降順
  • temperatures.winter 昇順
  • temperatures.winter 降順
  • neighborhoods 配列の内容インデックス(昇順および降順)

複合インデックス

  • city_name 昇順、neighborhoods 配列
  • city_name 降順、neighborhoods 配列

インデックス エントリ

このインデックス構成により、このドキュメントには次のインデックス エントリが作成されます。

インデックス インデックス登録されたデータ
単一フィールド インデックス エントリ
city_name 昇順 city_name: "San Francisco"
city_name 降順 city_name: "San Francisco"
temperatures.summer 昇順 temperatures.summer: 67
temperatures.summer 降順 temperatures.summer: 67
temperatures.winter 昇順 temperatures.winter: 55
temperatures.winter 降順 temperatures.winter: 55
neighborhoods 配列の内容インデックス昇順 neighborhoods: "Mission"
neighborhoods 配列の内容インデックス降順 neighborhoods: "Mission"
neighborhoods 配列の内容インデックス昇順 neighborhoods: "Downtown"
neighborhoods 配列の内容インデックス降順 neighborhoods: "Downtown"
neighborhoods 配列の内容インデックス昇順 neighborhoods: "Marina"
neighborhoods 配列の内容インデックス降順 neighborhoods: "Marina"
複合インデックスのエントリ
city_name 昇順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Mission"
city_name 昇順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Downtown"
city_name 昇順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Marina"
city_name 降順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Mission"
city_name 降順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Downtown"
city_name 降順、neighborhoods 配列 city_name: "San Francisco"、neighborhoods: "Marina"

インデックスと料金

インデックスはアプリケーションのストレージの費用の対象です。インデックスのストレージ サイズの計算方法について詳しくは、インデックス エントリのサイズをご覧ください。

インデックス マージの使用

Firestore ではすべてのクエリにインデックスを使用しますが、クエリごとに必ず 1 つのインデックスが必要になるわけではありません。複数の等式(==)句(およびオプションで orderBy 句)が含まれるクエリに対しては、Firestore は既存のインデックスを再利用できます。Firestore では、シンプルな等式フィルタのインデックスをマージして、より大規模な等式クエリに必要な複合インデックスを作成できます。

インデックス マージを使用できる状況を特定すると、インデックスの費用を削減できます。たとえば、レストランを評価するアプリに restaurants というコレクションがある場合を考えます。

  • restaurants

    • burgerthyme

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

このアプリは、以下のようなクエリを使用します。categorycityeditors_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")

それぞれのクエリに対してインデックスを作成するという方法が考えられます。

コレクション インデックス登録されるフィールド クエリのスコープ
レストラン category, star_rating コレクション
レストラン city, star_rating コレクション
レストラン category, city, star_rating コレクション
レストラン category, city, editors_pick, star_rating コレクション

より適切なソリューションとして、等式句のインデックスをマージする Firestore の機能を利用してインデックスの数を減らすことができます。

コレクション インデックス登録されるフィールド クエリのスコープ
レストラン category, star_rating コレクション
レストラン city, star_rating コレクション
レストラン editors_pick, star_rating コレクション

このインデックス セットはサイズが小さくなっただけでなく、次のような追加のクエリもサポートします。

ウェブ
db.collection("restaurants").where("editors_pick", "==", true)
                            .orderBy("star_rating")

インデックスの制限

インデックスには以下の上限が適用されます。割り当てと上限については、割り当てと上限をご覧ください。

このページでは、Firestore のリクエストの割り当てと上限について説明します。

上限 詳細
データベース 1 つあたりの複合インデックスの最大数
データベース 1 つあたりの単一フィールド構成の最大数

1 つのフィールド レベルの構成に、同じフィールドの構成を複数含めることができます。たとえば、単一フィールド インデックス除外と、同じフィールドに対する TTL ポリシーは、上限に対して 1 つのフィールド構成としてカウントされます。

ドキュメントごとのインデックス エントリの最大数

40,000

インデックス エントリの数は、ドキュメントに関する次の数の合計です。

  • 単一フィールド インデックス エントリ数
  • 複合インデックス エントリ数

Firestore がドキュメントと一連のインデックスをインデックス エントリに変換する仕組みについては、このインデックス エントリ数の例をご覧ください。

複合インデックス内のフィールドの最大数 100
インデックス エントリの最大サイズ

7.5 KiB

Firestore でインデックス エントリのサイズを計算する方法については、インデックス エントリのサイズをご覧ください。

ドキュメントのインデックス エントリの最大合計サイズ

8 MiB

合計サイズは、ドキュメントに関する次の数の合計です。

  • ドキュメントの単一フィールド インデックス エントリの合計サイズ
  • ドキュメントの複合インデックス エントリの合計サイズ
  • インデックス登録されるフィールド値の最大サイズ

    1,500 バイト

    1,500 バイトを超えるフィールド値は切り捨てられます。切り捨てられたフィールド値が含まれるクエリからは、整合性のない結果が返されることがあります。

    インデックスに関するベスト プラクティス

    ほとんどのアプリでは、自動インデックス作成とエラー メッセージのリンクを使用してインデックスを管理できます。ただし、以下のケースについては、単一フィールド除外を追加したほうがいい場合があります。

    ケース 説明
    大きな文字列フィールド

    文字列フィールドに長い文字列値を保持することが多く、その文字列値がクエリには使用されない場合、インデックス作成からそのフィールドを除外することでストレージの費用を削減できます。

    コレクションへの書き込みレートが高く、連続した値を持つドキュメントが含まれる

    コレクション内のドキュメント間で順次に増加または減少するフィールド(タイムスタンプなど)のインデックスを作成する場合は、コレクションへの最大書き込みレートは 500 回/秒です。連続した値を持つフィールドに基づいてクエリを実行することがない場合は、そのフィールドをインデックス作成から除外すれば、この上限を回避できます。

    たとえば、書き込みレートが高い IoT のユースケースでは、タイムスタンプ フィールドを持つドキュメントを含むコレクションは、500 回/秒の書き込み上限に近づく可能性があります。

    TTL フィールド

    TTL(有効期間)ポリシーを使用する場合は、TTL フィールドをタイムスタンプにする必要があります。TTL フィールドのインデックス登録はデフォルトで有効になっており、トラフィック レートが高くなるとパフォーマンスに影響する可能性があります。TTL フィールドには、単一フィールド除外を追加することをおすすめします。

    大規模な配列フィールドまたはマップ フィールド

    大規模な配列フィールドまたはマップ フィールドの場合、インデックス エントリの上限となっている、ドキュメントあたり 40,000 件に近づく可能性があります。大規模な配列フィールドまたはマップ フィールドに基づいてクエリを実行することがない場合は、そのフィールドをインデックス作成から除外してください。

    複数のフィールドで範囲演算子と不等式演算子を含むクエリを使用している場合は、Firestore クエリのパフォーマンスとコストを最適化するために考慮すべき検討事項のインデックス登録をご覧ください。

    インデックス登録の問題(インデックス ファンアウト、INVALID_ARGUMENT エラー)を解決する方法について詳しくは、トラブルシューティング ページをご覧ください。