Modèle de données

Firestore est une base de données NoSQL orientée documents. Contrairement à une base de données SQL, il n'y a ni tables, ni lignes. À la place, vous stockez les données dans des documents organisés en collections.

Chaque document contient un ensemble de paires clé/valeur. Firestore est optimisé pour le stockage de grandes collections composées de petits documents.

Tous les documents doivent être stockés dans des collections. Les documents peuvent contenir des sous-collections et des objets imbriqués qui peuvent tous deux être constitués de champs de données élémentaires, tels que des chaînes, ou d'objets complexes, tels que des listes.

Dans Firestore, les collections et les documents sont créés implicitement. Il vous suffit d'attribuer des données à un document au sein d'une collection. Si la collection ou le document n'existe pas, Firestore le crée.

Documents

Dans Firestore, l'unité de stockage est le document. Un document est un enregistrement de données allégé qui contient des champs correspondant à des valeurs. Chaque document est identifié par un nom.

Voici un exemple de document représentant un utilisateur alovelace :

  • alovelace

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

Les objets complexes imbriqués dans un document sont appelés cartes. Ainsi, dans l'exemple ci-dessus, vous pouvez structurer le nom de l'utilisateur à l'aide d'une carte, comme ceci :

  • alovelace

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

Vous remarquerez peut-être que les documents ressemblent beaucoup à du JSON. C'est parce qu'ils sont basés sur ce format. Même si des différences existent (par exemple, les documents acceptent davantage de types de données et leur taille est limitée à 1 Mo), vous pouvez généralement considérer que les documents sont des enregistrements JSON allégés.

Collections

Les documents se trouvent dans des collections, qui sont de simples conteneurs. Par exemple, vous pouvez créer une collection users pour accueillir vos différents utilisateurs, chacun représenté par un document :

  • users

    • alovelace

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

    • aturing

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

Firestore est un système de bases de données sans schéma. Vous disposez ainsi d'une liberté totale quant aux champs que vous placez dans chaque document et aux types de données que vous stockez dans ces champs. Les documents d'une même collection peuvent tous contenir des champs différents ou stocker différents types de données dans ces champs. Toutefois, lorque vous créez plusieurs documents, il est conseillé d'utiliser des champs et types de données similaires afin de pouvoir plus facilement effectuer des requêtes sur l'ensemble.

Une collection ne contient rien d'autre que des documents. Elle ne peut pas contenir directement de champs bruts associés à des valeurs ni contenir d'autres collections. Pour plus d'informations sur la façon de structurer des données plus complexes dans Firestore, reportez-vous à la page Données hiérarchiques.

Les noms des documents d'une collection doivent être uniques. Vous pouvez fournir vos propres clés, telles que des identifiants d'utilisateur, ou laisser Firestore générer des identifiants aléatoires automatiquement.

Il n'est pas nécessaire de créer ou de supprimer des collections. Une collection existe dès lors qu'un premier document y est créé. Si vous supprimez tous les documents d'une collection, elle n'existe plus.

Références

Dans Firestore, chaque document est identifiable de manière unique en fonction de sa position dans la base de données. L'exemple précédent présentait un document alovelace placé dans la collection users. Pour mentionner cet emplacement dans votre code, vous pouvez lui associer une référence.

Web
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
Android
DocumentReference alovelaceDocumentRef = db.collection("users").document("alovelace");
Kotlin + KTX
Android
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')
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('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")

Une référence est un objet léger qui pointe simplement vers un emplacement de votre base de données. Vous pouvez créer une référence même s'il n'existe aucune donnée. La création d'une référence n'exécute aucune opération réseau.

Vous pouvez également créer des références à des collections :

Web
var usersCollectionRef = db.collection('users');
Swift
let usersCollectionRef = db.collection("users")
Objective-C
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];
Java
Android
CollectionReference usersCollectionRef = db.collection("users");
Kotlin + KTX
Android
val usersCollectionRef = db.collection("users")
Java
// Reference to the collection "users"
CollectionReference collection = db.collection("users");
Python
users_ref = db.collection(u'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('users');
Unity
CollectionReference collectionRef = db.Collection("users");
C#
CollectionReference collectionRef = db.Collection("users");
Ruby
collection_ref = firestore.col "users"

Pour des raisons pratiques, vous avez également la possibilité de créer des références en spécifiant le chemin d'accès d'un document ou d'une collection sous forme de chaîne dont les éléments sont séparés par une barre oblique (/). Par exemple, voici comment créer une référence au document alovelace :

Web
var alovelaceDocumentRef = db.doc('users/alovelace');
Swift
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
FIRDocumentReference *aLovelaceDocumentReference =
    [self.db documentWithPath:@"users/alovelace"];
Java
Android
DocumentReference alovelaceDocumentRef = db.document("users/alovelace");
Kotlin + KTX
Android
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')
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"

Données hiérarchiques

Pour comprendre le fonctionnement des structures de données hiérarchiques dans Firestore, prenons l'exemple d'une application de chat contenant des messages et des salons de discussion.

Vous pouvez créer une collection appelée rooms pour stocker différents salons de discussion :

  • rooms

    • roomA

      name : "my chat room"

    • roomB

      ...

Maintenant que vous avez créé une collection de salons de discussion, choisissez comment stocker les messages. Il serait préférable de ne pas les stocker dans le document du salon de discussion, car dans Cloud Firestore, les documents doivent être légers. Or, un salon de discussion peut contenir un nombre important de messages. Toutefois, vous pouvez créer des collections supplémentaires dans le document de votre salon de discussion, sous la forme de sous-collections.

Sous-collections

Dans ce cas de figure, le meilleur moyen de stocker les messages consiste à utiliser des sous-collections. Une sous-collection est une collection associée à un document spécifique.

Dans votre collection rooms, vous pouvez créer une sous-collection appelée messages pour chaque document de salon de discussion :

  • rooms

    • roomA

      name : "my chat room"

      • messages

        • message1

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

        • message2

          ...

    • roomB

      ...

Dans cet exemple, une référence à un message de la sous-collection est créée à l'aide du code suivant :

Web
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
Android
DocumentReference messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1");
Kotlin + KTX
Android
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')
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")

Notez l'alternance des collections et des documents. Vos collections et vos documents doivent toujours respecter ce format. Vous ne pouvez pas référencer de collection dans une collection ou de document dans un document.

Les sous-collections vous permettent de structurer les données de manière hiérarchique pour les rendre plus accessibles. Pour obtenir tous les messages dans roomA, vous pouvez créer une référence à une sous-collection messages, puis interagir avec elle comme vous le feriez avec toute autre référence à une collection.

Les documents des sous-collections peuvent également contenir des sous-collections, ce qui vous permet d'imbriquer davantage de données. Vous pouvez imbriquer jusqu'à 100 niveaux de données.