Thi*_*ryC 16 firebase google-cloud-firestore
使用Firebase实时数据库,我们只需通过调用remove ()
父节点就可以删除一个包含单个命令的大量项目(节点已被删除,所有节点也都是子节点).
但是根据Firestore的文档(https://firebase.google.com/docs/firestore/manage-data/delete-data#collections):
要删除一个Collection,我们必须编写一个将遍历所有它的批处理文件并逐一删除.
这根本没有效率.是因为Firestore是测试版还是在一次调用中删除整个节点(Collection)在结构上是不可能的?
Gil*_*ert 22
RTDB能够执行此操作,因为每个数据库都是单个区域的本地数据库.为了提供序列化视图,在您调用时remove()
,数据库将停止所有其他工作,直到删除完成.
此行为导致了几个明显的中断:如果remove()
调用必须删除大量数据,则所有其他活动在完成之前都会被有效锁定.因此,即使对于想要删除大量数据的RTDB用户,我们也建议以组的形式递归查找和删除文档(CLI,node.js).
另一方面,Firestore基于更传统的Google风格的存储基础架构,其中不同的密钥范围被动态分配给不同的服务器(存储实际上不受BigTable支持,但适用相同的原则).这意味着删除数据不再是单个区域操作,并且有效地使删除显示为事务性变得非常昂贵.Firestore事务目前仅限于100个参与者,这意味着任何非平凡的事务性批量删除都是不可能的.
我们正在研究如何最好地表现出一个批量删除的API,而没有承诺的事务行为.可以直接想象如何从移动客户端执行此操作,但正如您所看到的,如果我们所做的只是为您嵌入循环和批量删除,则效率不高.我们也不想让REST客户成为二等公民.
Firestore是一种新产品,还有很多事情要做.不幸的是,这还没有削减.虽然这是我们希望最终解决的问题,但我无法提供任何时间表.
与此同时,控制台和firebase命令行都提供了一种非事务性的方法,例如用于测试自动化.
感谢您对Firestore的理解和感谢!
我很高兴从Realtime Database重构我的Firestore应用程序,享受更短的代码和更简单的语法,直到我重构了delete()函数!要删除带有子集的文档:
get()
一个子集合,没有进一步的子集合.forEach()
函数以读取子集合中的每个文档.Promise.all(arrayOfPromises)
要等到所有的子集已被删除.使用多层集合和文档,您可以将其作为一个函数,然后从另一个函数调用它以获得下一个更高层,等等.
您可以在控制台中看到这一点.要手动删除集合和文档,请删除最右侧的文档,然后删除最右侧的集合,依此类推.
这是我在AngularJS中的代码.仅当在子集合之前未删除顶级集合时,它才有效.
$scope.deleteClip = function(docId) {
if (docId === undefined) {
docId = $scope.movieOrTvShow + '_' + $scope.clipInMovieModel;
}
$scope.languageVideos = longLanguageFactory.toController($scope.language) + 'Videos';
var promises = [];
firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceTranslations').get()
.then(function(translations) {
translations.forEach(function(doc) {
console.log(doc.id);
promises.push(firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceTranslations').doc(doc.id).delete());
});
});
firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceExplanations').get()
.then(function(explanations) {
explanations.forEach(function(doc) {
console.log(doc.id);
promises.push(firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceExplanations').doc(doc.id).delete());
});
});
Promise.all(promises).then(function() {
console.log("All subcollections deleted.");
firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).delete()
.then(function() {
console.log("Collection deleted.");
$scope.clipInMovieModel = null;
$scope.$apply();
})
.catch(function(error) {
console.log("Remove failed: " + error.message);
});
})
.catch(function(error){
console.log("Error deleting subcollections: " + error);
});
};
Run Code Online (Sandbox Code Playgroud)
所有这些都是实时数据库中的一行.
这是删除集合中所有文档的最快方法:混合使用python 删除集合循环和python 批处理方法
def delete_collection(coll_ref, batch_size, counter):
batch = db.batch()
init_counter=counter
docs = coll_ref.limit(500).get()
deleted = 0
for doc in docs:
batch.delete(doc.reference)
deleted = deleted + 1
if deleted >= batch_size:
new_counter= init_counter + deleted
batch.commit()
print("potentially deleted: " + str(new_counter))
return delete_collection(coll_ref, batch_size, new_counter)
batch.commit()
delete_collection(db.collection(u'productsNew'), 500, 0)
Run Code Online (Sandbox Code Playgroud)
这会以 500 个块为单位从集合“productNew”中删除所有文档,这是当前可以传递给提交的最大文档数。请参阅Firebase 写入和事务配额。
您可以变得更复杂并处理 API 错误,但这对我来说很好用。
归档时间: |
|
查看次数: |
4735 次 |
最近记录: |