Modifier des données avec des opérations de pipeline

Utilisez les étapes du langage de manipulation de données (LMD) update(...) et delete(...) pour créer des pipelines de données qui peuvent interroger des documents, puis supprimer ou modifier des données.

Édition requise

Les opérations décrites sur cette page nécessitent l'édition Firestore Enterprise.

Avant de commencer

Vous devez savoir comment interroger une base de données avec des opérations de pipeline.

Mettre à jour des documents

Utilisez l'étape LMD update(...) pour créer des pipelines de données qui peuvent interroger des documents, puis ajouter ou modifier des données.

Toutes les étapes DML doivent se trouver à la fin du pipeline. Les documents qui arrivent à cette étape doivent inclure le champ __name__ pour identifier les documents à mettre à jour. L'opération échoue si l'un des documents que vous tentez de mettre à jour n'existe pas.

Par exemple, l'opération suivante remplit une modification de modèle de données dans tous les documents d'un groupe de collections. Le pipeline ajoute un champ preferences.color à tous les documents du groupe de collections users qui ne comportent pas ce champ.

Node.js
const snapshot = await db.pipeline()
   .collectionGroup("users")
   .where(not(exists(field("preferences.color"))))
   .addFields(constant(null).as("preferences.color"))
   .removeFields("color")
   .update()
   .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Constant, Field, Not

snapshot = (
    client.pipeline()
    .collection_group("users")
    .where(Not(Field.of("preferences.color").exists()))
    .add_fields(Constant.of(None).as_("preferences.color"))
    .remove_fields("color")
    .update()
    .execute()
)
Java
Pipeline.Snapshot snapshot = firestore.pipeline()
   .collectionGroup("users")
   .where(not(exists(field("preferences.color"))))
   .addFields(constant((String) null).as("preferences.color"))
   .removeFields("color")
   .update()
   .execute().get();

Supprimer des documents

Utilisez les étapes LMD delete(...) stage pour créer des pipelines de données qui peuvent interroger des documents, puis supprimer des données. Pour éviter les suppressions groupées accidentelles, les pipelines se terminant par delete(...) doivent inclure au moins une étape where(...). Toutes les étapes DML doivent se trouver à la fin du pipeline.

Par exemple, le pipeline suivant supprime tous les users documents dont le champ address.users est défini sur USA et dont le champ __create_time__ est inférieur à 10 jours :

Node.js
const pipeline = db.pipeline()
  .collectionGroup("users")
  .where(field("address.country").equal("USA"))
  .where(field("__create_time__").timestampAdd("day", 10).lessThan(currentTimestamp()))
  .delete();
await pipeline.execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import CurrentTimestamp, Field

snapshot = (
    client.pipeline()
    .collection_group("users")
    .where(Field.of("address.country").equal("USA"))
    .where(
        Field.of("__create_time__")
        .timestamp_add("day", 10)
        .less_than(CurrentTimestamp())
    )
    .delete()
    .execute()
)
Java
Pipeline.Snapshot deleteResults = firestore.pipeline()
  .collectionGroup("users")
  .where(field("address.country").equal("USA"))
  .where(field("__create_time__").add(constant(10)).lessThan(currentTimestamp()))
  .delete()
  .execute().get();

Cohérence

Les opérations de pipeline avec les étapes update(...) et delete() ne sont pas compatibles dans une transaction. Les étapes LMD s'exécutent en dehors d'une transaction avec le comportement suivant :

  • Chaque document est mis à jour indépendamment. Cela signifie que les opérations ne sont pas atomiques entre les documents. L'opération échoue lors de la première erreur et une réussite partielle est possible.
  • Les étapes suivantes sont compatibles :
    • collection(...)
    • collection_group(...)
    • where(...)
    • select(...)
    • add_fields(...)
    • remove_fields(...)
    • let(...)
    • sort(...)
    • limit(...)
    • offset(...)
  • Les étapes suivantes ne sont pas compatibles :
    • aggregate(...)
    • distinct(...)
    • unnest(...)
    • find_nearest(...)
    • Les étapes multi-requêtes telles que union(...), les jointures et les sous-requêtes ne sont pas autorisées avant une étape LMD.

Limites

Notez les limites suivantes pour les étapes LMD :

  • Les étapes LMD doivent être les dernières étapes d'une définition de pipeline avant d'appeler .execute().
  • Les opérations de pipeline avec les étapes update(...) et delete() ne sont pas compatibles dans une transaction.
  • Si l'étape précédant l'étape LMD génère plusieurs documents portant le même __name__, chaque instance est traitée. Pour update(...), cela signifie que le même document cible peut être modifié plusieurs fois. Pour delete(...), les tentatives suivantes après la première seront des no-ops.