Modifica datos con operaciones de Pipeline

Usa las etapas del lenguaje de manipulación de datos (DML) update(...) y delete(...) para construir canalizaciones de datos que puedan consultar documentos y, luego, borrar o modificar datos.

Requisitos de la edición

Las operaciones que se describen en esta página requieren la edición Enterprise de Firestore.

Antes de comenzar

Debes estar familiarizado con la forma de consultar una base de datos con operaciones de Pipeline.

Actualiza documentos

Usa la etapa DML update(...) para construir canalizaciones de datos que puedan consultar documentos y, luego, agregar o modificar datos.

Todas las etapas DML deben estar al final de la canalización. Los documentos que ingresan a esta etapa deben incluir el campo __name__ para identificar qué documentos actualizar. La operación falla si no existe ninguno de los documentos que intentas actualizar.

Por ejemplo, la siguiente operación propaga un cambio en el modelo de datos a todos los documentos de un grupo de colecciones. La canalización agrega un campo preferences.color a todos los documentos del grupo de colecciones users que no tienen ese campo.

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

Borra documentos

Usa la etapa DML delete(...) para construir canalizaciones de datos que puedan consultar documentos y, luego, borrar datos. Para evitar borrados masivos accidentales, las canalizaciones que terminan en delete(...) deben incluir al menos una etapa where(...). Todas las etapas DML deben estar al final de la canalización.

Por ejemplo, la siguiente canalización borra todos los documentos users con address.users configurado como USA y con __create_time__ inferior a 10 días:

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

Coherencia

Las operaciones de Pipeline con etapas update(...) y delete() no son compatibles dentro de una transacción. Las etapas DML se ejecutan fuera de una transacción con el siguiente comportamiento:

  • Cada documento se actualiza de forma independiente. Esto significa que las operaciones no son atómicas en todos los documentos. La operación falla en el primer error y es posible que se realice de forma parcial.
  • Se admiten las siguientes etapas:
    • collection(...)
    • collection_group(...)
    • where(...)
    • select(...)
    • add_fields(...)
    • remove_fields(...)
    • let(...)
    • sort(...)
    • limit(...)
    • offset(...)
  • No se admiten las siguientes etapas:
    • aggregate(...)
    • distinct(...)
    • unnest(...)
    • find_nearest(...)
    • No se permiten etapas de varias consultas como union(...), uniones y subconsultas antes de una etapa DML.

Limitaciones

Ten en cuenta las siguientes limitaciones para las etapas DML:

  • Las etapas DML deben ser las últimas etapas en una definición de canalización antes de llamar a .execute().
  • Las operaciones de Pipeline con etapas update(...) y delete() no son compatibles dentro de una transacción.
  • Si la etapa anterior a la etapa DML produce varios documentos con el mismo __name__, se procesa cada instancia. Para update(...), esto significa que el mismo documento de destino se puede modificar varias veces. Para delete(...), los intentos posteriores después del primero serán no-ops.