我正在尝试使用Firestore
管理时间戳更新包含500多个文档的集合中的字段timestamp
。
const batch = db.batch();
const serverTimestamp = admin.firestore.FieldValue.serverTimestamp();
db
.collection('My Collection')
.get()
.then((docs) => {
serverTimestamp,
}, {
merge: true,
})
.then(() => res.send('All docs updated'))
.catch(console.error);
这将引发错误
{ Error: 3 INVALID_ARGUMENT: cannot write more than 500 entities in a single call
at Object.exports.createStatusError (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\common.js:87:15)
at Object.onReceiveStatus (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:1188:28)
at InterceptingListener._callNext (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:614:8)
at callback (C:\Users\Growthfile\Desktop\cf-test\functions\node_modules\grpc\src\client_interceptors.js:841:24)
code: 3,
metadata: Metadata { _internal_repr: {} },
details: 'cannot write more than 500 entities in a single call' }
有没有一种方法,我可以写一个递归的方法,创建一个批处理对象,一个一个地更新一批500个文档,直到所有的文档都被更新。
从文档中,我知道删除操作可以使用这里提到的递归方法:
https://firebase.google.com/docs/firestore/manage-data/delete-data#collections
但是,对于更新,我不知道如何结束执行,因为文档没有被删除。
8条答案
按热度按时间yptwkmov1#
我喜欢这个简单的解决方案:
只要记住在顶部添加
import * as _ from "lodash"
。基于this answer。lbsnaicq2#
您可以使用默认BulkWriter。此方法使用500/50/5规则。
示例:
eqqqjvef3#
如上所述,@塞巴斯蒂安的回答很好,我也投了赞成票。虽然在一次性更新25000多个文档时遇到了一个问题。逻辑调整如下。
yc0p9oo04#
对先前评论的解释已经说明了这个问题。
我分享了我为自己构建和工作的最终代码,因为我需要以一种更解耦的方式工作的东西,而不是上面介绍的大多数解决方案的工作方式。
fd3cxomn5#
简单的解决方案只是发射两次?我的数组是“resultsFinal”我发射一次批与限制490,第二次与限制长度的数组(results.lenght)工作对我来说很好:)你怎么检查它?你去firebase和删除你的收集,firebase说你删除XXX文档,相同的长度你的数组?好的,所以你是好去
8wigbo566#
基于以上所有答案,我将以下代码片段放在一起,可以将它们放入JavaScript后端和前端的模块中,以便轻松使用Firestore批写入,而不必担心500次写入的限制。
后端(Node.js)
前端
9rnv2umw7#
没有引用或文档,这个代码是我自己发明的,对我来说它工作,看起来干净,简单的阅读和使用。如果有人喜欢它,那么也可以使用它。
最好进行自动测试,因为代码使用私有变量
_ops
,该变量可以在软件包升级后更改。例如,在旧版本中,它可以是_mutations
用法:
nszi6y058#
我也遇到了这个问题,以更新500多个文档内的Firestore收集。我想分享我是如何解决这个问题的。
我使用云函数在Firestore中更新我的集合,但这也应该在客户端代码上工作。
该解决方案计算对批处理执行的每个操作,在达到限制后,将创建一个新批处理并将其推送到
batchArray
。完成所有更新后,代码循环通过
batchArray
并提交数组内的每个批处理。对批次进行的每个操作
set(), update(), delete()
进行计数非常重要,因为它们都计数到500个操作限制。