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 數據庫不同,它沒有表或行。相反,你存儲在文檔中的數據,其被組織成集合

每個文件包含了一組鍵-值對。 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。事實上,他們基本上是。存在一些差異(例如,文檔支持額外的數據類型並且大小限制為 1 MB),但一般而言,您可以將文檔視為輕量級 JSON 記錄。

收藏

文檔存在於集合中,集合只是文檔的容器。例如,你可以有一個users集合包含您的各種用戶,各由一個文件表示:

  • 用戶

    • alovelace

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

    • aturing

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

Cloud Firestore 是無模式的,因此您可以完全自由地決定在每個文檔中放置哪些字段以及在這些字段中存儲哪些數據類型。同一集合中的文檔都可以包含不同的字段或在這些字段中存儲不同類型的數據。但是,最好在多個文檔中使用相同的字段和數據類型,以便您可以更輕鬆地查詢文檔。

一個集合包含文檔而不是其他任何東西。它不能直接包含帶有值的原始字段,也不能包含其他集合。 (見層次數據為如何在雲結構的FireStore更複雜的數據的解釋。)

集合中文檔的名稱是唯一的。您可以提供自己的密鑰,例如用戶 ID,也可以讓 Cloud Firestore 自動為您創建隨機 ID。

您不需要“創建”或“刪除”集合。在集合中創建第一個文檔後,集合就存在了。如果您刪除集合中的所有文檔,它就不再存在。

參考

Cloud Firestore 中的每個文檔都由其在數據庫中的位置唯一標識。前面的例子顯示出文件alovelace集合中users 。要引用這個位置在你的代碼,你可以創建對它的引用

網頁版 9

import { doc } from "firebase/firestore";

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

網頁版 8

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

爪哇

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

科特林+KTX

val alovelaceDocumentRef = db.collection("users").document("alovelace")
爪哇
// 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");
節點.js
const alovelaceDocumentRef = db.collection('users').doc('alovelace');
alovelaceRef := client.Collection("users").Doc("alovelace")
PHP
$document = $db->collection('samples/php/users')->document('lovelace');
統一
DocumentReference documentRef = db.Collection("users").Document("alovelace");
C#
DocumentReference documentRef = db.Collection("users").Document("alovelace");
紅寶石
document_ref = firestore.col("users").doc("alovelace")

引用是一個輕量級對象,它只指向數據庫中的某個位置。無論數據是否存在,您都可以創建引用,並且創建引用不會執行任何網絡操作。

您還可以創建到集合的引用:

網頁版 9

import { collection } from "firebase/firestore";

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

網頁版 8

var usersCollectionRef = db.collection('users');
迅速
let usersCollectionRef = db.collection("users")
目標-C
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];

爪哇

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

科特林+KTX

val usersCollectionRef = db.collection("users")
爪哇
// 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");
節點.js
const usersCollectionRef = db.collection('users');
usersRef := client.Collection("users")
PHP
$collection = $db->collection('samples/php/users');
統一
CollectionReference collectionRef = db.Collection("users");
C#
CollectionReference collectionRef = db.Collection("users");
紅寶石
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');
迅速
let aLovelaceDocumentReference = db.document("users/alovelace")
目標-C
FIRDocumentReference *aLovelaceDocumentReference =
    [self.db documentWithPath:@"users/alovelace"];

爪哇

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

科特林+KTX

val alovelaceDocumentRef = db.document("users/alovelace")
爪哇
// 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");
節點.js
const alovelaceDocumentRef = db.doc('users/alovelace');
alovelaceRef := client.Doc("users/alovelace")
PHP
$document = $db->document('users/lovelace');
統一
DocumentReference documentRef = db.Document("users/alovelace");
C#
DocumentReference documentRef = db.Document("users/alovelace");
紅寶石
document_path_ref = firestore.doc "users/alovelace"

分層數據

要了解分層數據結構在 Cloud Firestore 中的工作原理,請考慮一個包含消息和聊天室的示例聊天應用。

您可以創建一個名為集rooms ,以存儲不同的聊天室:

    • roomA

      name : "my chat room"

    • roomB

      ...

現在您有聊天室,決定如何存儲您的消息。您可能不想將它們存儲在聊天室的文檔中。 Cloud Firestore 中的文檔應該是輕量級的,聊天室可以包含大量消息。但是,您可以在聊天室文檔中創建其他集合作為子集合。

子集

在這種情況下存儲消息的最佳方法是使用子集合。子集合是與特定文檔關聯的集合。

您可以創建一個子集合稱為messages在你的每一個房間的文檔rooms收集:

    • roomA

      name : "my chat room"

      • 消息

        • MESSAGE1

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

        • 消息2

          ...

    • 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');
迅速
let messageRef = db
    .collection("rooms").document("roomA")
    .collection("messages").document("message1")
目標-C
FIRDocumentReference *messageRef =
    [[[[self.db collectionWithPath:@"rooms"] documentWithPath:@"roomA"]
    collectionWithPath:@"messages"] documentWithPath:@"message1"];

爪哇

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

科特林+KTX

val messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1")
爪哇
// 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");
節點.js
const messageRef = db.collection('rooms').doc('roomA')
  .collection('messages').doc('message1');
messageRef := client.Collection("rooms").Doc("roomA").
	Collection("messages").Doc("message1")
PHP
$document = $db
    ->collection('rooms')
    ->document('roomA')
    ->collection('messages')
    ->document('message1');
統一
DocumentReference documentRef = db
	.Collection("Rooms").Document("RoomA")
	.Collection("Messages").Document("Message1");
C#
DocumentReference documentRef = db
    .Collection("Rooms").Document("RoomA")
    .Collection("Messages").Document("Message1");
紅寶石
message_ref = firestore.col("rooms").doc("roomA").col("messages").doc("message1")

注意集合和文檔的交替模式。您的集合和文檔必須始終遵循此模式。您不能引用集合中的集合或文檔中的文檔。

子集合允許您按層次結構構建數據,使數據更易於訪問。要得到所有信息roomA ,您可以創建一個集合參考子集合messages ,並與之交互就像使用任何其他集合引用。

子集合中的文檔也可以包含子集合,允許您進一步嵌套數據。您最多可以嵌套 100 級深度的數據。