简体   繁体   English

如何从 Firestore 中删除集合或子集合?

[英]How delete a collection or subcollection from Firestore?

I have a collection called lists and it has documents who is ID represents the list ID.我有一个名为列表的集合,它包含 ID 代表列表 ID 的文档。 This document has a collection called employees and another one called locations .该文档有一个名为employees的集合和另一个名为locations的集合。

The structure looks like this:结构如下所示:

(lists)
    -listId
       (employees)
       (locations)

If the user wants to delete a specific list then the problem is that we can't delete listId because that will keep the collection (as was mentioned by Firestore docs).如果用户想要删除特定列表,那么问题是我们无法删除 listId,因为这将保留集合(如 Firestore 文档所述)。

How can the structure be modeled to fit the needs?如何对结构进行建模以满足需求? I can't seem to get around the need for subcollection.我似乎无法绕过子集合的需要。

Any recommendation?有什么推荐吗?

There is no need to restructure your database in order to delete some collections.无需为了删除某些集合而重构数据库。 To delete an entire collection or subcollection in Cloud Firestore, retrieve all the documents within the collection or subcollection and delete them.要删除 Cloud Firestore 中的整个集合或子集合,请检索集合或子集合中的所有文档并将其删除。 So in order to delete a specific list, please use the following steps:因此,要删除特定列表,请使用以下步骤:

  1. Find all documents beneath employees collection and delete them查找employees集合下的所有文档并删除它们
  2. Find all documents beneath locations collection and delete them查找locations集合下的所有文档并删除它们
  3. Delete the listId document删除listId文档

If you have larger collections, you may want to delete the documents in smaller batches to avoid out-of-memory errors.如果您有较大的集合,您可能希望以较小的批次删除文档以避免内存不足错误。 Repeat the process until you've deleted the entire collection or subcollection.重复该过程,直到您删除了整个集合或子集合。

Even if the delete operation is not recomended by Firebase team because it has negative security and performance implications , you can still do it but only for small collections.即使 Firebase 团队不推荐删除操作,因为它对has negative security and performance implications ,您仍然可以这样做,但仅限于小型集合。 If you need to delete entire collections for web, do so only from a trusted server environment.如果您需要删除整个网络收藏,请仅从受信任的服务器环境中执行此操作。

For Android, you can use the following code:对于 Android,您可以使用以下代码:

private void deleteCollection(final CollectionReference collection, Executor executor) {
    Tasks.call(executor, () -> {
        int batchSize = 10;
        Query query = collection.orderBy(FieldPath.documentId()).limit(batchSize);
        List<DocumentSnapshot> deleted = deleteQueryBatch(query);

        while (deleted.size() >= batchSize) {
            DocumentSnapshot last = deleted.get(deleted.size() - 1);
            query = collection.orderBy(FieldPath.documentId()).startAfter(last.getId()).limit(batchSize);

            deleted = deleteQueryBatch(query);
        }

        return null;
    });
}

@WorkerThread
private List<DocumentSnapshot> deleteQueryBatch(final Query query) throws Exception {
    QuerySnapshot querySnapshot = Tasks.await(query.get());

    WriteBatch batch = query.getFirestore().batch();
    for (DocumentSnapshot snapshot : querySnapshot) {
        batch.delete(snapshot.getReference());
    }
    Tasks.await(batch.commit());

    return querySnapshot.getDocuments();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM