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 データモデル

Cloud Firestore は NoSQL ドキュメント指向データベースです。SQL データベースとは違い、テーブルや行はありません。代わりに、データは「ドキュメント」に格納し、それが「コレクション」にまとめられます。

各「ドキュメント」には、一連の Key-Value ペアが含まれています。Cloud Firestore は、小型のドキュメントの大きなコレクションを格納するために最適化されています。

すべてのドキュメントはコレクションに保存する必要があります。ドキュメントには、「サブコレクション」と、ネストされたオブジェクトを格納できます。このどちらにも、文字列などの基本フィールドや、リストなどの複雑なオブジェクトを含めることができます。

コレクションとドキュメントは Cloud Firestore で暗黙的に作成されます。ユーザーはデータをコレクション内のドキュメントに割り当てるだけです。コレクションまたはドキュメントのいずれかが存在しない場合は、Cloud Firestore によって作成されます。

ドキュメント

Cloud Firestore では、ストレージの単位はドキュメントになります。ドキュメントは、値にマッピングされるフィールドを含む軽量のレコードです。各ドキュメントは名前で識別されます。

ユーザー alovelace を表すドキュメントは次のようになります。

  • alovelace

    first : "Ada"
    last : "Lovelace"
    born : 1815

ドキュメント内の複雑なネストされたオブジェクトはマップと呼ばれます。たとえば、上記の例のユーザー名をマップで構造化すると、次のようになります。

  • alovelace

    name :
        first : "Ada"
        last : "Lovelace"
    born : 1815

見てわかるように、ドキュメントは JSON によく似ており、実際基本的には JSON と同じです。いくつかの違いはありますが(たとえばドキュメントでは追加のデータ型がサポートされており、サイズは 1 MB までに制限されています)、一般的にドキュメントは軽量の JSON レコードとして扱うことができます。

コレクション

ドキュメントはコレクションの中にあります。コレクションは単なるドキュメントのコンテナです。たとえば、users コレクションを作成して、さまざまなユーザーを表すドキュメントを格納できます。

  • users

    • alovelace

      first : "Ada"
      last : "Lovelace"
      born : 1815

    • aturing

      first : "Alan"
      last : "Turing"
      born : 1912

Cloud Firestore はスキーマレスなので、各ドキュメントにどのフィールドを入れるかやそのフィールドにどのデータ型を格納するかは、完全に自由に決めることができます。同じコレクション内のドキュメントすべてに異なるフィールドを含めたり、それらのフィールドに異なるデータ型を格納したりもできます。ただし、複数のドキュメントで同じフィールドとデータ型を使用するほうが、ドキュメントのクエリが容易になります。

コレクションにはドキュメントだけが含まれます。コレクションに値を持つ生のフィールドを直接含めることはできず、他のコレクションを含めることもできません。Cloud Firestore でより複雑なデータを構造化する方法については、階層データをご覧ください。

コレクション内のドキュメントの名前は一意です。ユーザー ID などの独自のキーを指定することも、Cloud Firestore で自動的にランダムな ID を作成することもできます。

コレクションを「作成」したり「削除」したりする必要はありません。コレクション内の最初のドキュメントを作成すると、コレクションはすでに存在しています。コレクション内のすべてのドキュメントを削除すると、コレクションは存在しなくなります。

リファレンス

Cloud Firestore のすべてのドキュメントは、データベース内の場所によって一意に識別されます。前の例では、コレクション users 内のドキュメント alovelace を示しました。コード内でこの場所を参照するには、その場所への「リファレンス」を作成します。

ウェブ バージョン 9

import { doc } from "firebase/firestore";

const alovelaceDocumentRef = doc(db, 'users', 'alovelace');

ウェブ バージョン 8

var alovelaceDocumentRef = db.collection('users').doc('alovelace');
Swift
let alovelaceDocumentRef = db.collection("users").document("alovelace")
Objective-C
FIRDocumentReference *alovelaceDocumentRef =
    [[self.db collectionWithPath:@"users"] documentWithPath:@"alovelace"];

Java

DocumentReference alovelaceDocumentRef = db.collection("users").document("alovelace");

Kotlin+KTX

val alovelaceDocumentRef = db.collection("users").document("alovelace")
Java
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.collection("users").document("alovelace");
Python
a_lovelace_ref = db.collection(u'users').document(u'alovelace')

Python

a_lovelace_ref = db.collection("users").document("alovelace")
C++
DocumentReference alovelace_document_reference =
    db->Collection("users").Document("alovelace");
Node.js
const alovelaceDocumentRef = db.collection('users').doc('alovelace');
Go
alovelaceRef := client.Collection("users").Doc("alovelace")
PHP
$document = $db->collection('samples/php/users')->document('lovelace');
Unity
DocumentReference documentRef = db.Collection("users").Document("alovelace");
C#
DocumentReference documentRef = db.Collection("users").Document("alovelace");
Ruby
document_ref = firestore.col("users").doc("alovelace")

リファレンスは、データベース内の場所を参照するだけの軽量なオブジェクトです。リファレンスはそこにデータが存在するかどうかにかかわらず作成することができ、リファレンスを作成してもネットワーク操作は実行されません。

コレクションへのリファレンスも作成できます。

ウェブ バージョン 9

import { collection } from "firebase/firestore";

const usersCollectionRef = collection(db, 'users');

ウェブ バージョン 8

var usersCollectionRef = db.collection('users');
Swift
let usersCollectionRef = db.collection("users")
Objective-C
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];

Java

CollectionReference usersCollectionRef = db.collection("users");

Kotlin+KTX

val usersCollectionRef = db.collection("users")
Java
// Reference to the collection "users"
CollectionReference collection = db.collection("users");
Python
users_ref = db.collection(u'users')

Python

users_ref = db.collection("users")
C++
CollectionReference users_collection_reference = db->Collection("users");
Node.js
const usersCollectionRef = db.collection('users');
Go
usersRef := client.Collection("users")
PHP
$collection = $db->collection('samples/php/users');
Unity
CollectionReference collectionRef = db.Collection("users");
C#
CollectionReference collectionRef = db.Collection("users");
Ruby
collection_ref = firestore.col "users"

便宜上、ドキュメントまたはコレクションへのパスを文字列として指定し、パス コンポーネントをスラッシュ(/)で区切ってリファレンスを作成することもできます。たとえば、alovelace ドキュメントへのリファレンスは次のように作成します。

ウェブ バージョン 9

import { doc } from "firebase/firestore";

const alovelaceDocumentRef = doc(db, 'users/alovelace');

ウェブ バージョン 8

var alovelaceDocumentRef = db.doc('users/alovelace');
Swift
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
FIRDocumentReference *aLovelaceDocumentReference =
    [self.db documentWithPath:@"users/alovelace"];

Java

DocumentReference alovelaceDocumentRef = db.document("users/alovelace");

Kotlin+KTX

val alovelaceDocumentRef = db.document("users/alovelace")
Java
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.document("users/alovelace");
Python
a_lovelace_ref = db.document(u'users/alovelace')

Python

a_lovelace_ref = db.document("users/alovelace")
C++
DocumentReference alovelace_document = db->Document("users/alovelace");
Node.js
const alovelaceDocumentRef = db.doc('users/alovelace');
Go
alovelaceRef := client.Doc("users/alovelace")
PHP
$document = $db->document('users/lovelace');
Unity
DocumentReference documentRef = db.Document("users/alovelace");
C#
DocumentReference documentRef = db.Document("users/alovelace");
Ruby
document_path_ref = firestore.doc "users/alovelace"

階層データ

Cloud Firestore で階層データ構造がどのように機能するかを理解するために、メッセージとチャットルームを使ったチャットアプリの例を見てみましょう。

さまざまなチャットルームを格納するための rooms と呼ばれるコレクションを作成できます。

  • rooms

    • roomA

      name : "my chat room"

    • roomB

      ...

これでチャットルームができたので、メッセージを保存する方法を指定します。チャットルームのドキュメントには保存したくない場合もあるでしょう。Cloud Firestore 内のドキュメントは軽量にする必要があり、チャットルームには膨大な数のメッセージが格納される可能性があります。ただし、チャットルームのドキュメント内にサブコレクションとして追加のコレクションを作成できます。

サブコレクション

このシナリオでメッセージを保存するための最善の方法は、サブコレクションを使用することです。サブコレクションは特定のドキュメントに関連付けられたコレクションです。

rooms コレクション内のすべてのルーム ドキュメントに、messages というサブコレクションを作成できます。

  • rooms

    • roomA

      name : "my chat room"

      • messages

        • message1

          from : "alex"
          msg : "Hello World!"

        • message2

          ...

    • roomB

      ...

この例では、次のコードを使用して、サブコレクション内のメッセージへのリファレンスを作成します。

ウェブ バージョン 9

import { doc } from "firebase/firestore";

const messageRef = doc(db, "rooms", "roomA", "messages", "message1");

ウェブ バージョン 8

var messageRef = db.collection('rooms').doc('roomA')
                .collection('messages').doc('message1');
Swift
let messageRef = db
    .collection("rooms").document("roomA")
    .collection("messages").document("message1")
Objective-C
FIRDocumentReference *messageRef =
    [[[[self.db collectionWithPath:@"rooms"] documentWithPath:@"roomA"]
    collectionWithPath:@"messages"] documentWithPath:@"message1"];

Java

DocumentReference messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1");

Kotlin+KTX

val messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1")
Java
// Reference to a document in subcollection "messages"
DocumentReference document =
    db.collection("rooms").document("roomA").collection("messages").document("message1");
Python
room_a_ref = db.collection(u'rooms').document(u'roomA')
message_ref = room_a_ref.collection(u'messages').document(u'message1')

Python

room_a_ref = db.collection("rooms").document("roomA")
message_ref = room_a_ref.collection("messages").document("message1")
C++
DocumentReference message_reference = db->Collection("rooms")
    .Document("roomA")
    .Collection("messages")
    .Document("message1");
Node.js
const messageRef = db.collection('rooms').doc('roomA')
  .collection('messages').doc('message1');
Go
messageRef := client.Collection("rooms").Doc("roomA").
	Collection("messages").Doc("message1")
PHP
$document = $db
    ->collection('rooms')
    ->document('roomA')
    ->collection('messages')
    ->document('message1');
Unity
DocumentReference documentRef = db
	.Collection("Rooms").Document("RoomA")
	.Collection("Messages").Document("Message1");
C#
DocumentReference documentRef = db
    .Collection("Rooms").Document("RoomA")
    .Collection("Messages").Document("Message1");
Ruby
message_ref = firestore.col("rooms").doc("roomA").col("messages").doc("message1")

コレクションとドキュメントが交互になるよう注意してください。コレクションとドキュメントは常にこのパターンに従う必要があります。コレクション内のコレクションや、ドキュメント内のドキュメントは参照できません。

サブコレクションを使用すると、データを階層的に構造化できるため、データへのアクセスが容易になります。roomA にあるすべてのメッセージを取得するために、サブコレクション messages へのコレクション リファレンスを作成して、それを他のコレクション リファレンスと同じように操作できます。

サブコレクション内のドキュメントにもサブコレクションを格納できるため、データをさらにネストできます。データは最大 100 レベルまでネストできます。