【问题标题】:How to list subcollections in a Cloud Firestore document如何在 Cloud Firestore 文档中列出子集合
【发布时间】:2018-03-17 17:12:01
【问题描述】:

假设我将这个最小的数据库存储在 Cloud Firestore 中。如何检索subCollection1subCollection2 的名称?

rootCollection {
    aDocument: {
        someField: { value: 1 },
        anotherField: { value: 2 }
        subCollection1: ...,
        subCollection2: ...,
    }
}

我希望能够仅读取 aDocument 的 ID,但只有当我 get() 文档时才会显示字段。

rootRef.doc('aDocument').get()
  .then(doc =>

    // only logs [ "someField", "anotherField" ], no collections
    console.log( Object.keys(doc.data()) )
  )

【问题讨论】:

  • 程序员不应该事先知道集合吗?你的用例是什么?
  • @VictorNascimento。用例处理缺少递归删除。我正在尝试删除其中包含子集合的文档,并且这些子集合也应该被删除,因为它们是文档的子集合并且不再有效。是的,目前我碰巧知道集合的名称,但是为了删除单个文档而需要手动枚举可能无限深度的树上的每个子集合是很糟糕的做法。
  • 子集合不是用于引用它们的父文档的成员/属性。
  • 递归删除可以在 Admin SDK 中和通过 CLI 完成。请参阅文档here

标签: javascript firebase google-cloud-firestore


【解决方案1】:

在 Node.js 中,您将使用“ListCollectionIds”方法

var firestore = require('firestore.v1beta1');

var client = firestore.v1beta1({
  // optional auth parameters.
});

// Iterate over all elements.
var formattedParent = client.anyPathPath("[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]");

client.listCollectionIds({parent: formattedParent}).then(function(responses) {
    var resources = responses[0];
    for (var i = 0; i < resources.length; ++i) {
        // doThingsWith(resources[i])
    }
})
.catch(function(err) {
    console.error(err);
});

客户端 SDK(Web、iOS、Android)目前不支持此功能。

【讨论】:

  • 不完全是好消息,但至少它即将到来。感谢更新。关于当前可用的递归删除带有子集合的文档的技术有什么建议吗?
  • @Dan McGrath Firestore 只是云数据存储更名了吗?
  • @skylize -> 触发一个云函数来执行它。
  • @DimuDesigns -> 没有。
  • @Dan McGrath 触发云功能有何帮助?您是说ListCollectionIds现在在 Cloud Functions 中可用?
【解决方案2】:

似乎他们在 Node.js 中添加了一个名为 getCollections() 的方法:

firestore.doc(`/myCollection/myDocument`).getCollections().then(collections => {
  for (let collection of collections) {
    console.log(`Found collection with id: ${collection.id}`);
  }
});

此示例打印出/myCollection/myDocument 处文档的所有子集合

【讨论】:

  • 这看起来很有希望。由于这个问题,我不得不放弃使用 Firestore,并且没有机会再试一次。我希望我的问题能给其他人带来更好的体验。如果按照您的建议解决了这个问题,那么我希望我有机会再试一次。
【解决方案3】:

the documentation里不是详细的吗?

/**
 * Delete a collection, in batches of batchSize. Note that this does
 * not recursively delete subcollections of documents in the collection
 */
function deleteCollection(db, collectionRef, batchSize) {
    var query = collectionRef.orderBy('__name__').limit(batchSize);

    return new Promise(function(resolve, reject) {
        deleteQueryBatch(db, query, batchSize, resolve, reject);
    });
}

function deleteQueryBatch(db, query, batchSize, resolve, reject) {
    query.get()
        .then((snapshot) => {
            // When there are no documents left, we are done
            if (snapshot.size == 0) {
                return 0;
            }

            // Delete documents in a batch
            var batch = db.batch();
            snapshot.docs.forEach(function(doc) {
                batch.delete(doc.ref);
            });

            return batch.commit().then(function() {
                return snapshot.size;
            });
        }).then(function(numDeleted) {
            if (numDeleted <= batchSize) {
                resolve();
                return;
            }

            // Recurse on the next process tick, to avoid
            // exploding the stack.
            process.nextTick(function() {
                deleteQueryBatch(db, query, batchSize, resolve, reject);
            });
        })
        .catch(reject);
}

【讨论】:

  • 在您在此处发布的所有代码中,与我的问题相关的唯一部分是顶部的注释,“这不会递归删除集合中文档的子集合”。我的具体预期用例是手动递归子集合,以便我可以使用文档中的说明删除它们。然而由于某种疯狂的原因,我无法获得子集合列表来知道要删除什么。
  • 你有什么发现吗?
  • doc.data().someField.subCollection1 or doc.data().someField.subCollection1.val() or doc.data().someField.subCollection1.val?
猜你喜欢
  • 2021-12-16
  • 1970-01-01
  • 2018-04-14
  • 2018-10-09
  • 2018-05-10
  • 2018-11-19
相关资源
最近更新 更多