Firestore 파이프라인 작업으로 데이터 수정하기

update(...)delete(...) 데이터 조작 언어 (DML) 단계를 사용하여 문서를 쿼리한 후 데이터를 삭제하거나 수정할 수 있는 데이터 파이프라인을 구성합니다.

버전 요구사항

이 페이지에 설명된 작업에는 Firestore Enterprise 버전이 필요합니다.

시작하기 전에

파이프라인 작업으로 데이터베이스를 쿼리하는 방법을 잘 알고 있어야 합니다.

문서 업데이트

update(...) DML 단계를 사용하여 문서를 쿼리한 후 데이터를 추가하거나 수정할 수 있는 데이터 파이프라인 을 구성합니다.

모든 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()
)
자바
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();

문서 삭제

delete(...) 단계 DML 단계를 사용하여 문서를 쿼리한 후 데이터를 삭제할 수 있는 데이터 파이프라인 을 구성합니다. 실수로 대량 삭제하는 것을 방지하려면 delete(...)로 끝나는 파이프라인에 하나 이상의 where(...) 단계가 포함되어야 합니다. 모든 DML 단계는 파이프라인의 끝에 있어야 합니다.

예를 들어 다음 파이프라인은 users 문서 중 address.usersUSA로 설정되고 __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()
)
자바
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(...)의 경우 첫 번째 시도 후의 후속 시도는 노옵스(no-ops)입니다.