我如何使用一个事务来更新firestore中的多个集合,我搜索了这个事务却没有得到任何答案。是否可以在一个事务中更新多个集合?我想在教室和学生集合中立即更新****分支
e0bqpujr1#
正如Node.js客户端库update()方法的文档中所解释的,它返回一个Transaction,该Transaction是“用于链接方法调用”。(请注意,Admin SDK的update()方法的行为完全相同)。因此,例如,如果在事务中要从教室文档获取一个值,增加该值并使用它更新两个不同集合(classrooms和students)中的两个文档,则应执行以下操作:
update()
Transaction
classrooms
students
const db = firebase.firestore(); //or admin.firestore() in a Cloud Function const docRef1 = db.collection('classrooms').doc('classroomDocId'); const docRef2 = db.collection('students').doc('studentDocId'); let transaction = db.runTransaction(t => { let newNumericValue; return t.get(docRef1 ) .then(doc => { newNumericValue = doc.data().numericValue + 1; //You calculate the new value return t.update(docRef1 , {numericValue : newNumericValue}); }).then(t => { return t.update(docRef2 , {numericValue : newNumericValue}); }); }).then(result => { console.log('Transaction success!' + result); }).catch(err => { console.log('Transaction failure:', err); });
请注意,如果您需要在多次更新之前执行多次读取,“当使用事务时,读取操作必须在写入操作之前”。另一方面,如果您只想更新多个文档而不阅读一个或多个值(您在问题中说您“想要branch.name在教室和学生集合中一次性更新www.example.com“),则不需要使用事务,只需使用批处理写入,如下所示:
let batch = db.batch(); let cRef = db.collection('classrooms').doc('classroomDocId'); batch.set(cRef, {branch.name: 'newName'}); let sRef = db.collection('students').doc('studentDocId'); batch.update(sRef, {branch.name: 'newName'}); return batch.commit().then(function () { // ... });
根据您的意见更新
在您的云函数中,您可以很好地链接不同的Firestore查询(使用where()),并在每个then()中填充批处理,然后在最后一个then()中提交批处理。
where()
then()
let batch = admin.firestore().batch(); return admin.firestore().collection('students').where('branch.id', '==', documentId).get() .then((querySnapshot) => { querySnapshot.forEach((doc) => { batch.update(doc.ref, {branch: {id: documentId, name: after.name}}); }); return admin.firestore().collection('student_public').where('branch.id', '==', documentId).get(); }) .then((querySnapshot) => { querySnapshot.forEach((doc) => { batch.update(doc.ref, {branch: {id: documentId, name: after.name}}); }); return batch.commit() }) .catch(err => { console.log('error===>', err); });
1条答案
按热度按时间e0bqpujr1#
正如Node.js客户端库
update()
方法的文档中所解释的,它返回一个Transaction
,该Transaction
是“用于链接方法调用”。(请注意,Admin SDK的update()
方法的行为完全相同)。因此,例如,如果在事务中要从教室文档获取一个值,增加该值并使用它更新两个不同集合(
classrooms
和students
)中的两个文档,则应执行以下操作:请注意,如果您需要在多次更新之前执行多次读取,“当使用事务时,读取操作必须在写入操作之前”。
另一方面,如果您只想更新多个文档而不阅读一个或多个值(您在问题中说您“想要branch.name在教室和学生集合中一次性更新www.example.com“),则不需要使用事务,只需使用批处理写入,如下所示:
根据您的意见更新
在您的云函数中,您可以很好地链接不同的Firestore查询(使用
where()
),并在每个then()
中填充批处理,然后在最后一个then()
中提交批处理。