Firestore获取根集合的所有文档和子集合

时间:2017-10-22 15:41:39

标签: firebase google-cloud-firestore

说我有这种结构

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

其中AB集合,而ab文档
有没有办法通过一个查询获取根文档中包含的所有内容?
如果我这样查询

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

我刚收到name:'Tim'字段。我想要的也是获得所有B的文件。
我基本上希望我的查询返回

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

是否可能或者我真的需要为每个集合进行多次查询:/?

假设我有一个非常深的嵌套树集合代表用户配置文件,我的成本会像地狱一样提高,因为每次加载用户配置文件时我都有一个读取请求的倍数1 x N其中N是深度我的树:/。

3 个答案:

答案 0 :(得分:20)

如果您担心每次拉动的成本,您需要根据您的共同视图/拉动需求来构建数据,而不是您可能更喜欢完美结构。如果你需要每次都把这些东西放在一起,Consider using "maps"用于那些实际上不需要带有文档的子集合。

在此示例中,“首选项”是一个地图。

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

每个文档的大小也限制为1MB - 因此,如果您需要为此用户存储可扩展并继续增长的内容(如日志记录),那么将日志分成仅限于此的子集合是有意义的在你想要它时被拉出来,使每个日志条目成为一个单独的文件......并且所有用户的所有日志是否都存储在一个单独的父集合中,或者每个用户的子集合是否真的取决于你将如何提取日志和什么将导致快速,平衡拉动成本。如果您向用户显示他们的最后10次搜索,那么搜索日志作为子集合会很有意义。如果您要为所有用户提取所有搜索数据以进行分析,那么单独的父级别集合将有意义,因为您可以将所有日志拉入1次,以防止需要单独从每个用户提取日志。

为方便起见,您还可以将拉力和承诺嵌套在一起。

  // 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);
  });

答案 1 :(得分:17)

正如我们所知,Cloud Firestore中的查询默认情况下很浅。不支持此类查询,但Google可能会考虑将来这样做。

答案 2 :(得分:3)

添加到Matt R答案,如果你正在使用babel或者你可以使用async / await,你可以用更少的代码获得相同的结果(没有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);
    })
});
相关问题