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

r4i*_*id4 38 firebase google-cloud-firestore

说我有这种结构

    A (collection): { 
       a (doc): {
           name:'Tim',
           B (collection):{
               b (doc): {
                      color:'blue'
               }
             }
          }
    }
Run Code Online (Sandbox Code Playgroud)

在哪里AB集合,a而且b文档.
有没有办法通过一个查询获取根文档中包含的所有内容?
如果我这样查询

db.collection("A").doc("a").get()
Run Code Online (Sandbox Code Playgroud)

我刚刚name:'Tim'上场.我想要的是获得所有B的文件.
我基本上希望我的查询返回

         {
           user:'Tim',
           B (collection):{
               b (doc): {
                      color:'blue'
               }
             }
          }
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*out 27

如果您担心每次拉动的成本,您将需要根据您的共同视图/拉动需求来构建数据,而不是您可能更喜欢完美结构.如果您每次都需要将这些东西放在一起,请考虑使用"地图"来处理实际上不需要包含文档的子集合.

在此示例中,"首选项"是地图.

{
  user: "Tim",
  preferences: {
      color: "blue",
      nickname: "Timster"
  }
}
Run Code Online (Sandbox Code Playgroud)

每个文档的大小也限制为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);
  });
Run Code Online (Sandbox Code Playgroud)


J P*_*ash 22

正如我们所知,Cloud Firestore中的查询默认情况下很浅.虽然这是Google未来可能会考虑的问题,但不支持此类查询.

  • @AshClarke,collectionGroup查询将跨文档查询特定名称的所有子集合,但查询仍然很浅,并且不会返回整个文档树。此外,一旦获得查询结果,就无法获取“所属”文档(默认情况下)。您可以将父 docID 存储在子集合文档中,并使用该值来检索父文档,但这不是自动的。 (7认同)
  • 现在受支持:https://firebase.googleblog.com/2019/06/understanding-collection-group-queries.html (3认同)
  • @AshClarke 我浏览了这篇文章,但不明白该怎么做,你能将其作为答案发布并提及我吗?或引导我走向正确的方向? (2认同)

Or *_*uan 5

添加到Matt R答案中,如果您使用babel或可以使用async / await,则可以用更少的代码(no 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);
    })
});
Run Code Online (Sandbox Code Playgroud)