web-dev-qa-db-fra.com

Comment faire une mise à jour groupée dans Firestore

J'utilise Cloud Firestore et j'ai une collection de documents. Pour chaque document de la collection, je voudrais mettre à jour l'un des champs.

L'utilisation d'une transaction pour effectuer la mise à jour serait inefficace car je n'ai pas besoin de lire les données lors de la mise à jour.

Les mises à jour par lots semblent être la bonne direction, mais les documents n'incluent pas d'exemples de mise à jour de plusieurs documents à la fois. Voir ici: Ecritures par lots

9
Trey Granderson

Si vous avez utilisé la base de données Firebase, il n'était pas possible d'écrire sur des emplacements séparés complètement uniques, c'est pourquoi vous devez utiliser des écritures par lots, ce qui signifie que toutes les opérations réussissent ou qu'aucune d'entre elles n'est appliquée.

Concernant Firestore, toutes les opérations sont désormais traitées atomiquement. Cependant, vous pouvez exécuter plusieurs opérations d'écriture en tant que lot unique contenant toute combinaison d'opérations set (), update () ou delete (). Un lot d'écritures se termine de manière atomique et peut écrire sur plusieurs documents.

Il s'agit d'un exemple simple concernant une opération par lots pour une opération d'écriture, de mise à jour et de suppression.

WriteBatch batch = db.batch();

DocumentReference johnRef = db.collection("users").document("John");
batch.set(johnRef, new User());

DocumentReference maryRef = db.collection("users").document("Mary");
batch.update(maryRef, "Anna", 20); //Update name and age

DocumentReference alexRef = db.collection("users").document("Alex");
batch.delete(alexRef);

batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        // ...
    }
});

L'appel de la méthode commit() sur l'objet batch signifie que vous validez l'intégralité du batch.

11
Alex Mamo

Je cherchais une solution, je n'en ai trouvé aucune, alors j'ai fait celle-ci, si quelqu'un est intéressé.

public boolean bulkUpdate() {
  try {
    // see https://firebase.google.com/docs/firestore/quotas#writes_and_transactions
    int writeBatchLimit = 500;
    int totalUpdates = 0;

    while (totalUpdates % writeBatchLimit == 0) {
      WriteBatch writeBatch = this.firestoreDB.batch();

      List<QueryDocumentSnapshot> documentsInBatch =
          this.firestoreDB.collection("animals")
              .whereEqualTo("species", "cat")
              .limit(writeBatchLimit)
              .get()
              .get()
              .getDocuments();

      if (documentsInBatch.isEmpty()) {
        break;
      }

      documentsInBatch.forEach(
          document -> writeBatch.update(document.getReference(), "hasTail", true));

      writeBatch.commit().get();

      totalUpdates += documentsInBatch.size();
    }

    System.out.println("Number of updates: " + totalUpdates);

  } catch (Exception e) {
    return false;
  }
  return true;
}
0
Jordi Reinsma