Daten mit Firestore-Pipelinevorgängen ändern

Verwenden Sie die DML-Phasen (Data Manipulation Language, Datenbearbeitungssprache) update(...) und delete(...), um Datenpipelines zu erstellen, mit denen Dokumente abgefragt und Daten gelöscht oder geändert werden können.

Anforderungen an die Version

Für die auf dieser Seite beschriebenen Vorgänge ist die Firestore Enterprise-Version erforderlich.

Hinweis

Sie sollten mit dem Abfragen einer Datenbank mit Pipeline-Vorgängen vertraut sein.

Dokumente aktualisieren

Verwenden Sie die update(...)-DML-Phase, um Datenpipelines zu erstellen, mit denen Dokumente abgefragt und dann Daten hinzugefügt oder geändert werden können.

Alle DML-Phasen müssen am Ende der Pipeline stehen. Die Dokumente, die in diese Phase gelangen, müssen das Feld __name__ enthalten, um anzugeben, welche Dokumente aktualisiert werden sollen. Der Vorgang schlägt fehl, wenn eines der Dokumente, die Sie aktualisieren möchten, nicht vorhanden ist.

Mit dem folgenden Vorgang wird beispielsweise eine Änderung des Datenmodells für alle Dokumente in einer Sammlungsgruppe nachgetragen. Mit der Pipeline wird allen Dokumenten in der Sammlungsgruppe users, denen dieses Feld fehlt, das Feld preferences.color hinzugefügt.

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)

Dokumente löschen

Verwenden Sie die DML-Phasen der delete(...)-Phase, um Datenpipelines zu erstellen, mit denen Dokumente abgefragt und Daten gelöscht werden können. Um versehentliche Massenlöschungen zu vermeiden, sollten Pipelines, die mit delete(...) enden, mindestens eine where(...)-Phase enthalten. Alle DML-Phasen müssen am Ende der Pipeline stehen.

Mit der folgenden Pipeline werden beispielsweise alle users-Dokumente gelöscht, bei denen address.users auf USA festgelegt ist und __create_time__ weniger als 10 Tage beträgt:

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)

Konsistenz

Pipelinevorgänge mit update(...)- und delete()-Phasen werden innerhalb einer Transaktion nicht unterstützt. DML-Phasen werden außerhalb einer Transaktion ausgeführt und haben das folgende Verhalten:

  • Jedes Dokument wird unabhängig aktualisiert. Das bedeutet, dass Vorgänge nicht dokumentübergreifend atomar sind. Der Vorgang schlägt beim ersten Fehler fehl und ein Teilerfolg ist möglich.
  • Die folgenden Phasen werden unterstützt:
    • collection(...)
    • collection_group(...)
    • where(...)
    • select(...)
    • add_fields(...)
    • remove_fields(...)
    • let(...)
    • sort(...)
    • limit(...)
    • offset(...)
  • Die folgenden Phasen werden nicht unterstützt:
    • aggregate(...)
    • distinct(...)
    • unnest(...)
    • find_nearest(...)
    • Phasen mit mehreren Abfragen wie union(...), Joins und Unterabfragen sind vor einer DML-Phase nicht zulässig.

Beschränkungen

Beachten Sie die folgenden Einschränkungen für DML-Phasen:

  • DML-Phasen müssen die letzten Phasen in einer Pipeline-Definition sein, bevor .execute() aufgerufen wird.
  • Pipelinevorgänge mit update(...)- und delete()-Phasen werden innerhalb einer Transaktion nicht unterstützt.
  • Wenn in der Phase vor der DML-Phase mehrere Dokumente mit derselben __name__ erstellt werden, wird jede Instanz verarbeitet. Für update(...) bedeutet das, dass dasselbe Zieldokument mehrmals geändert werden kann. Bei delete(...) sind nach dem ersten Versuch keine weiteren Versuche möglich.