如何建模此结构以处理删除

时间:2018-03-06 07:09:09

标签: android firebase google-cloud-firestore

我有一个名为lists的集合,它有一个ID代表列表ID的文档。该文档包含名为employees的集合,另一个名为locations

结构如下:

(lists)
    -listId
       (employees)
       (locations)

如果用户想要删除特定列表,那么问题是我们无法删除listId,因为这将保留集合(如Firestore文档所述)。

如何对结构进行建模以满足需求。我似乎无法满足副收集的需要。

任何建议?

1 个答案:

答案 0 :(得分:1)

无需重新构建数据库以删除某些集合。要删除Cloud Firestore中的整个集合或子集合,请检索集合或子集合中的所有文档并将其删除。因此,要删除特定列表,请使用以下步骤:

  1. 查找employees集合下方的所有文档并将其删除
  2. 查找locations集合下方的所有文档并将其删除
  3. 删除listId文档
  4. 如果您有更大的集合,您可能希望以较小批量删除文档以避免内存不足错误。重复此过程,直到删除整个集合或子集合。

    即使Firebase团队没有推荐删除操作,因为它has negative security and performance implications,您仍然可以执行此操作,但仅适用于小型集合。如果您需要删除Web的整个集合,请仅从受信任的服务器环境中删除。

    对于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();
    }