Firestore obtenir tous les docs et les sous-collectionsde la collecte de racine

disons que j'ai ce genre de structure

    A (collection): { 
       a (doc): {
           name:'Tim',
           B (collection):{
               b (doc): {
                      color:'blue'
               }
             }
          }
    }

A et B collectionsa et b documents.

Est-il un moyen pour obtenir tout ce qui est contenu dans un document racine avec une seule requête?

Si j'ai une requête comme ceci

db.collection("A").doc("a").get()

je viens de devient name:'Tim' champ. Ce que je veux, c'est aussi avoir tous les documents de B.

Je souhaite que ma requête retourne

         {
           user:'Tim',
           B (collection):{
               b (doc): {
                      color:'blue'
               }
             }
          }

Est-ce possible ou dois-je vraiment besoin de faire de multiples questions, un pour chaque collection :/ ?

disons que j'ai un arbre de collections imbriqué très profond représentant le profil de l'utilisateur, mes coûts vont augmenter comme l'enfer puisque chaque fois que je charge un profil d'utilisateur j'ai un multiplicateur de demandes de lecture 1 x N où N est la profondeur de mon arbre :/.

23
demandé sur r4id4 2017-10-22 18:41:38

3 réponses

comme nous le savons, les questions dans Cloud Firestore sont superficielles par défaut. Ce type de requête n'est pas pris en charge, bien que ce soit quelque chose que Google peut considérer dans le futur.

13
répondu J Prakash 2017-10-24 22:19:18

si vous êtes préoccupé par les coûts de chaque pull, vous aurez besoin de structurer vos données en fonction de vos besoins communs de vue / pull, plutôt que ce que vous pourriez préférer pour une structure parfaite. Si vous avez besoin de tirer ces choses ensemble, à chaque fois, envisagez d'utiliser "maps" pour les choses qui n'ont pas vraiment besoin d'être des sous-collections avec des documents.

Dans cet exemple, "préférences" est une carte.

{
  user: "Tim",
  preferences: {
      color: "blue",
      nickname: "Timster"
  }
}

chaque document est également limité en taille à 1MB-so si vous avez besoin de stocker quelque chose pour cet utilisateur qui va se dimensionner et continuer à se développer, comme des enregistrements de log, alors il serait logique de casser les logs dans une sous-collection qui est tiré seulement quand vous le voulez, faisant chaque entrée de log un document séparé... Et si tous les journaux pour tous les utilisateurs sont stockés dans une collection mère séparée, ou une sous-collection de chaque utilisateur dépend vraiment de la façon dont vous tirerez les journaux et ce qui se traduira par des vitesses rapides, équilibrées par rapport aux coûts des pulls. Si vous montrez ceci utilisez leurs 10 dernières recherches, puis un search-log serait bon sens comme une sous-collection. Si vous tirez toutes les données de recherche pour tous les utilisateurs pour l'analyse, alors une collecte séparée au niveau des parents serait logique parce que vous pouvez tirer tous les journaux en 1 pull, pour éviter la nécessité de tirer les journaux de chaque utilisateur séparément.

vous pouvez également emboîter vos pulls et promesses ensemble pour des raisons de commodité.

  // Get reference to all of the documents
  console.log("Retrieving list of documents in collection");
  let documents = collectionRef.limit(1).get()
    .then(snapshot => {
      snapshot.forEach(doc => {
        console.log("Parent Document ID: ", doc.id);

        let subCollectionDocs = collectionRef.doc(doc.id).collection("subCollection").get()
          .then(snapshot => {
            snapshot.forEach(doc => {
              console.log("Sub Document ID: ", doc.id);
            })
          }).catch(err => {
            console.log("Error getting sub-collection documents", err);
          })
      });
    }).catch(err => {
    console.log("Error getting documents", err);
  });
18
répondu Matthew Rideout 2017-10-26 03:20:06

ajouter à la réponse de Matt R, Si vous utilisez babel ou vous pouvez utiliser async / wait, vous pouvez obtenir le même résultat avec moins de code (non catch/then):

// Get reference to all of the documents
console.log("Retrieving list of documents in collection");
let documents = await collectionRef.get();

documents.forEach(async doc => {
  console.log("Parent Document ID: ", doc.id);
  let subCollectionDocs = await collectionRef.doc(doc.id).collection("subCollection").get()
  subCollectionDocs.forEach(subCollectionDoc => {
    subCollectionDoc.forEach(doc => {
      console.log("Sub Document ID: ", doc.id);
    })
});
1
répondu Or Duan 2017-12-05 15:02:34