แก้ไขข้อมูลด้วยการดำเนินการไปป์ไลน์ Firestore

ใช้ขั้นตอนภาษาในการจัดการข้อมูล (DML) update(...) และ delete(...) เพื่อสร้างไปป์ไลน์ข้อมูลที่สามารถค้นหาเอกสาร แล้วลบหรือแก้ไขข้อมูลได้

ข้อกำหนดของรุ่น

การดำเนินการที่อธิบายไว้ในหน้านี้ต้องใช้ Firestore รุ่น Enterprise

ก่อนเริ่มต้น

คุณควรคุ้นเคยกับวิธีค้นหาฐานข้อมูลด้วยการดำเนินการไปป์ไลน์

อัปเดตเอกสาร

ใช้ขั้นตอน 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();
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)

ลบเอกสาร

ใช้ขั้นตอน DML delete(...) stage เพื่อสร้างไปป์ไลน์ข้อมูล ที่สามารถค้นหาเอกสาร แล้วลบข้อมูลได้ ไปป์ไลน์ที่ลงท้ายด้วย delete(...) ควรมีขั้นตอน where(...) อย่างน้อย 1 ขั้นตอนเพื่อป้องกันการลบจำนวนมากโดยไม่ตั้งใจ ขั้นตอน 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();
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)

ความสอดคล้อง

ระบบไม่รองรับการดำเนินการไปป์ไลน์ที่มีขั้นตอน 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(...) การพยายามครั้งต่อๆ ไปหลังจากครั้งแรกจะไม่มีการดำเนินการ