Изменение данных с помощью операций Firestore Pipeline.

Используйте этапы языка манипулирования данными (DML) update(...) и delete(...) для построения конвейеров обработки данных, которые могут запрашивать документы, а затем удалять или изменять данные.

Требования к изданию

Для выполнения операций, описанных на этой странице, требуется Firestore Enterprise Edition.

Прежде чем начать

Вам следует знать, как выполнять запросы к базе данных с помощью операций Pipeline .

Обновить документы

Используйте этап DML update(...) для построения конвейеров обработки данных, которые могут запрашивать документы, а затем добавлять или изменять данные.

Все этапы DML должны выполняться в конце конвейера. Документы, поступающие на этот этап, должны содержать поле __name__ для идентификации документов, которые необходимо обновить. Операция завершится неудачей, если какой-либо из документов, которые вы пытаетесь обновить, не существует.

Например, следующая операция заполняет данные об изменении модели во всех документах группы коллекций. Конвейер добавляет поле preferences.color ко всем документам в группе коллекций users , у которых отсутствует это поле.

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

Удалить документы

Используйте этапы DML delete(...) для построения конвейеров обработки данных, которые могут запрашивать документы, а затем удалять данные. Чтобы предотвратить случайное массовое удаление, конвейеры, заканчивающиеся на delete(...) должны включать как минимум один этап where(...) . Все этапы DML должны располагаться в конце конвейера.

Например, следующий конвейер удаляет все документы users , у которых address.users установлено на USA и __create_time__ меньше 10 дней:

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

Последовательность

Операции конвейера с этапами update(...) и delete() не поддерживаются в рамках транзакции. Этапы DML выполняются вне транзакции со следующим поведением:

  • Каждый документ обновляется независимо. Это означает, что операции не являются атомарными для всех документов. Операция завершается с ошибкой при первом же срабатывании, и возможен частичный успех.
  • Поддерживаются следующие этапы:
    • collection(...)
    • collection_group(...)
    • where(...)
    • select(...)
    • add_fields(...)
    • remove_fields(...)
    • let(...)
    • sort(...)
    • limit(...)
    • offset(...)
  • Следующие этапы не поддерживаются:
    • aggregate(...)
    • distinct(...)
    • unnest(...)
    • find_nearest(...)
    • Многозапросные операции, такие как union(...) , соединения и подзапросы, не допускаются перед операцией DML.

Ограничения

Обратите внимание на следующие ограничения для этапов DML:

  • Этапы DML должны быть последними этапами в определении конвейера перед вызовом метода .execute() .
  • Операции конвейера с этапами update(...) и delete() не поддерживаются в рамках транзакции.
  • Если на этапе, предшествующем этапу DML, создается несколько документов с одинаковым __name__ , каждый экземпляр обрабатывается. Для update(...) это означает, что один и тот же целевой документ может быть изменен несколько раз. Для delete(...) последующие попытки после первой будут бездействовать.