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

אפשר להשתמש בשלבים של שפת הטיפול בנתונים (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();
המשך
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(...) כדי ליצור צינורות עיבוד נתונים שיכולים לשלוח שאילתות למסמכים ואז למחוק נתונים. כדי למנוע מחיקות בבת אחת בטעות, צינורות שמסתיימים ב-delete(...) צריכים לכלול לפחות where(...) שלב אחד. כל שלבי ה-DML חייבים להופיע בסוף צינור העיבוד.

לדוגמה, צינור הנתונים הבא מוחק את כל המסמכים users עם הערך USA בשדה address.users, ועם ערך של פחות מ-10 ימים בשדה __create_time__:

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