简体   繁体   English

Firestore交易在单个交易中更新多个集合

[英]Firestore transaction update multiple collections in a single transaction

How can i update multiple collections in firestore by using a single transaction i searched but i didn't get any answers. 如何使用搜索到的单个交易更新Firestore中的多个集合,但没有得到任何答案。 Is it possible to update multiple collections in a single transaction? 是否可以在单个事务中更新多个集合?

I want to update branch.name at-once in classroom & students collection 我想一次在教室和学生集合中更新 branch.name 在此处输入图片说明

在此处输入图片说明

As explained in the documentation for the Node.js Client Library update() method, it returns a Transaction which is " used for chaining method calls ." 如Node.js客户端库update()方法的文档所述,它返回一个Transaction ,“ 用于链接方法调用” (Note that update() method of the Admin SDK behaves exactly the same way). (请注意,Admin SDK的update()方法的行为完全相同)。

So, for example, if within the transaction you want to get a value from a classroom doc, increase it and use it to update two documents from two different collections ( classrooms and students ), you would do as follows: 因此,例如,如果在事务中您想从课堂文档中获取价值,增加它并使用它来更新来自两个不同集合( classroomsstudents )的两个文档,您将执行以下操作:

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);
});

Note that if you need to do several reads before your multiple updates, "when using transactions, read operations must come before write operations ." 请注意,如果您需要在多次更新之前进行多次读取,则“使用事务时, 读取操作必须先于写入操作”


On the other hand, IF YOU JUST WANT TO UPDATE multiple documents WITHOUT READING one or more values (you say in your question that you "want to update branch.name at-once in classroom & students collection "), you don't need to use a transaction. 另一方面, 如果您只是想在不读取一个或多个值的情况下更新多个文档(您在问题中说“您希望在教​​室和学生集合中一次更新一次branch.name”),则不需要使用交易。 Just use a batched write , as follows: 只需使用批处理write即可 ,如下所示:

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 () {
  // ...
});

UPDATE Following your comments 更新您的评论

In your Cloud Function, you can very well chain different Firestore queries (with where() ) and in each then() populate the batch and then in the last then() commit the batch. 在您的Cloud Function中,您可以很好地链接不同的Firestore查询(使用where() ),并在每个then()填充批次,然后在最后一个then()提交批次。 See below for an example (just adapt with the correct queries): 请参见下面的示例(仅使用正确的查询进行调整):

 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); });

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

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