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

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

ข้อกำหนดของแต่ละรุ่น

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

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

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

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

ใช้ขั้นตอน 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(...) อย่างน้อย 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();

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

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