שינוי נתונים באמצעות פעולות בצינור

אפשר להשתמש בשלבים של שפת הטיפול בנתונים (DML) update(...) ו-delete(...) כדי ליצור צינורות עיבוד נתונים שיכולים לשלוח שאילתות למסמכים ואז למחוק או לשנות נתונים.

דרישות לגבי מהדורות

הפעולות שמתוארות בדף הזה דורשות את מהדורת 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()
)
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 עם הערך USA בשדה address.users ועם ערך בשדה __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 חייבים להיות השלבים האחרונים בהגדרת צינור (pipeline) לפני הקריאה ל-.execute().
  • אי אפשר להשתמש בפעולות של צינורות עם שלבים update(...) ו-delete() בתוך טרנזקציה.
  • אם השלב שלפני שלב ה-DML מפיק כמה מסמכים עם אותו __name__, כל מופע יעבור עיבוד. במקרה של update(...), המשמעות היא שאותו מסמך יעד עשוי לעבור שינוי כמה פעמים. במקרה של delete(...), ניסיונות חוזרים אחרי הניסיון הראשון יהיו בלי תפעול (no-ops).