Modifica datos con operaciones de canalizaciones de Firestore

Usa las etapas update(...) y delete(...) del lenguaje de manipulación de datos (DML) 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 saber cómo consultar una base de datos con operaciones de Pipeline.

Actualiza documentos

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

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

Por ejemplo, la siguiente operación reabastece un cambio en el modelo de datos para 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();
Go
snapshot := client.Pipeline().
	CollectionGroup("users").
	Where(firestore.Not(firestore.FieldExists(firestore.FieldOf("preferences.color")))).
	AddFields(firestore.Selectables(
		firestore.ConstantOfNull().As("preferences.color"),
	)).
	RemoveFields(firestore.Fields("color")).
	Update().
	Execute(ctx)

Borra documentos

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

Por ejemplo, la siguiente canalización borra todos los documentos users con address.users establecido en 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();
Go
snapshot := client.Pipeline().
	CollectionGroup("users").
	Where(firestore.FieldOf("address.country").Equal("USA")).
	Where(firestore.FieldOf("__create_time__").Add(firestore.ConstantOf(10)).LessThan(firestore.CurrentTimestamp())).
	Delete().
	Execute(ctx)

Coherencia

Las operaciones de canalización con etapas update(...) y delete() no se admiten dentro de una transacción. Las etapas de 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 los documentos. La operación falla en el primer error, y es posible que se produzca un éxito 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(...)
    • Las etapas de varias consultas, como union(...), las uniones y las subconsultas, no se permiten antes de una etapa de DML.

Limitaciones

Ten en cuenta las siguientes limitaciones para las etapas de DML:

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