Sửa đổi dữ liệu bằng các thao tác trong quy trình Firestore

Sử dụng các giai đoạn Ngôn ngữ thao tác dữ liệu (DML) update(...)delete(...) để tạo các quy trình xử lý dữ liệu có thể truy vấn tài liệu, sau đó xoá hoặc sửa đổi dữ liệu.

Yêu cầu về phiên bản

Các thao tác được mô tả trên trang này yêu cầu phiên bản Firestore Enterprise.

Trước khi bắt đầu

Bạn nên làm quen với cách truy vấn cơ sở dữ liệu bằng các thao tác trong Quy trình xử lý dữ liệu.

Cập nhật tài liệu

Sử dụng giai đoạn DML update(...) để tạo các quy trình xử lý dữ liệu có thể truy vấn tài liệu, sau đó thêm hoặc sửa đổi dữ liệu.

Tất cả các giai đoạn DML phải nằm ở cuối quy trình xử lý dữ liệu. Các tài liệu đến giai đoạn này phải bao gồm trường __name__ để xác định những tài liệu cần cập nhật. Thao tác sẽ không thành công nếu bất kỳ tài liệu nào bạn cố gắng cập nhật không tồn tại.

Ví dụ: thao tác sau sẽ điền lại dữ liệu cho một thay đổi về mô hình dữ liệu vào tất cả tài liệu trong một nhóm bộ sưu tập. Quy trình xử lý dữ liệu sẽ thêm trường preferences.color vào tất cả tài liệu trong nhóm bộ sưu tập users bị thiếu trường đó.

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();
Bắt đầu
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)

Xoá tài liệu

Sử dụng các giai đoạn DML delete(...) stage để tạo các quy trình xử lý dữ liệu có thể truy vấn tài liệu, sau đó xoá dữ liệu. Để tránh việc vô tình xoá hàng loạt, các quy trình xử lý dữ liệu kết thúc bằng delete(...) phải có ít nhất một giai đoạn where(...). Tất cả các giai đoạn DML phải nằm ở cuối quy trình xử lý dữ liệu.

Ví dụ: quy trình xử lý dữ liệu sau sẽ xoá tất cả tài liệu usersaddress.users được đặt thành USA và có __create_time__ nhỏ hơn 10 ngày:

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();
Bắt đầu
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)

Tính nhất quán

Các thao tác trong quy trình xử lý dữ liệu có các giai đoạn update(...)delete() không được hỗ trợ trong một giao dịch. Các giai đoạn DML chạy bên ngoài một giao dịch với hành vi sau:

  • Mỗi tài liệu được cập nhật độc lập. Điều này có nghĩa là các thao tác không phải là thao tác nguyên tử trên các tài liệu. Thao tác sẽ không thành công khi gặp lỗi đầu tiên và có thể thành công một phần.
  • Các giai đoạn sau được hỗ trợ:
    • collection(...)
    • collection_group(...)
    • where(...)
    • select(...)
    • add_fields(...)
    • remove_fields(...)
    • let(...)
    • sort(...)
    • limit(...)
    • offset(...)
  • Các giai đoạn sau không được hỗ trợ:
    • aggregate(...)
    • distinct(...)
    • unnest(...)
    • find_nearest(...)
    • Các giai đoạn truy vấn nhiều lần như union(...), các phép nối và truy vấn con không được phép trước giai đoạn DML.

Hạn chế

Hãy lưu ý các hạn chế sau đối với các giai đoạn DML:

  • Các giai đoạn DML phải là các giai đoạn cuối cùng trong định nghĩa quy trình xử lý dữ liệu trước khi gọi .execute().
  • Các thao tác trong quy trình xử lý dữ liệu có các giai đoạn update(...)delete() không được hỗ trợ trong một giao dịch.
  • Nếu giai đoạn trước giai đoạn DML tạo ra nhiều tài liệu có cùng __name__, thì mỗi thực thể sẽ được xử lý. Đối với update(...), điều này có nghĩa là cùng một tài liệu đích có thể được sửa đổi nhiều lần. Đối với delete(...), các lần thử tiếp theo sau lần đầu tiên sẽ không hoạt động.