מחיקת מסמכים ושדות

בדוגמאות הבאות מוסבר איך למחוק מסמכים, שדות ואוספים.

מחיקת מסמכים

כדי למחוק מסמך, משתמשים בשיטות הבאות שספציפיות לשפה delete():

גרסה 9 לאינטרנט

משתמשים בשיטה deleteDoc():

import { doc, deleteDoc } from "firebase/firestore";

await deleteDoc(doc(db, "cities", "DC"));

גרסה 8 לאינטרנט

משתמשים ב-method‏ delete():

db.collection("cities").doc("DC").delete().then(() => {
    console.log("Document successfully deleted!");
}).catch((error) => {
    console.error("Error removing document: ", error);
});
Swift

משתמשים ב-method‏ delete():

הערה: המוצר הזה לא זמין ביעדים של watchOS ו-App Clip.
do {
  try await db.collection("cities").document("DC").delete()
  print("Document successfully removed!")
} catch {
  print("Error removing document: \(error)")
}
Objective-C

משתמשים ב-method‏ deleteDocumentWithCompletion::

הערה: המוצר הזה לא זמין ב-watchOS ובמטרות של קליפים של אפליקציות.
[[[self.db collectionWithPath:@"cities"] documentWithPath:@"DC"]
    deleteDocumentWithCompletion:^(NSError * _Nullable error) {
      if (error != nil) {
        NSLog(@"Error removing document: %@", error);
      } else {
        NSLog(@"Document successfully removed!");
      }
}];
‫Kotlin
Android

משתמשים ב-method‏ delete():

db.collection("cities").document("DC")
    .delete()
    .addOnSuccessListener { Log.d(TAG, "DocumentSnapshot successfully deleted!") }
    .addOnFailureListener { e -> Log.w(TAG, "Error deleting document", e) }
‫Java
Android

משתמשים בשיטה delete():

db.collection("cities").document("DC")
        .delete()
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.d(TAG, "DocumentSnapshot successfully deleted!");
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "Error deleting document", e);
            }
        });

Dart

משתמשים בשיטה delete():

db.collection("cities").doc("DC").delete().then(
      (doc) => print("Document deleted"),
      onError: (e) => print("Error updating document $e"),
    );
Java

משתמשים ב-method‏ delete():

// asynchronously delete a document
ApiFuture<WriteResult> writeResult = db.collection("cities").document("DC").delete();
// ...
System.out.println("Update time : " + writeResult.get().getUpdateTime());
Python

משתמשים ב-method‏ delete():

db.collection("cities").document("DC").delete()
Python
(Async)

משתמשים ב-method‏ delete():

await db.collection("cities").document("DC").delete()
C++‎

משתמשים בשיטה Delete():

db->Collection("cities").Document("DC").Delete().OnCompletion(
    [](const Future<void>& future) {
      if (future.error() == Error::kErrorOk) {
        std::cout << "DocumentSnapshot successfully deleted!" << std::endl;
      } else {
        std::cout << "Error deleting document: " << future.error_message()
                  << std::endl;
      }
    });
Node.js

משתמשים ב-method‏ delete():

const res = await db.collection('cities').doc('DC').delete();
המשך

משתמשים בשיטה Delete():


import (
	"context"
	"log"

	"cloud.google.com/go/firestore"
)

func deleteDoc(ctx context.Context, client *firestore.Client) error {
	_, err := client.Collection("cities").Doc("DC").Delete(ctx)
	if err != nil {
		// Handle any errors in an appropriate way, such as returning them.
		log.Printf("An error has occurred: %s", err)
	}

	return err
}
PHP

משתמשים בשיטה delete():

$db->collection('samples/php/cities')->document('DC')->delete();
Unity

משתמשים ב-method‏ DeleteAsync():

DocumentReference cityRef = db.Collection("cities").Document("DC");
cityRef.DeleteAsync();
C#‎

משתמשים בשיטה DeleteAsync():

DocumentReference cityRef = db.Collection("cities").Document("DC");
await cityRef.DeleteAsync();
Ruby

משתמשים בשיטה delete():

city_ref = firestore.doc "#{collection_path}/DC"
city_ref.delete

כשמוחקים מסמך, Firestore לא מוחק באופן אוטומטי את המסמכים בקולקציות המשנה שלו. עדיין אפשר לגשת למסמכים של אוסף המשנה באמצעות הפניה. לדוגמה, אפשר לגשת למסמך בנתיב /mycoll/mydoc/mysubcoll/mysubdoc גם אם מוחקים את מסמך ההורה ב-/mycoll/mydoc.

מסמכי הורה שלא קיימים מופיעים במסוף, אבל הם לא מופיעים בתוצאות של שאילתות וב-snapshots.

אם רוצים למחוק מסמך ואת כל המסמכים בקולקציות המשנה שלו, צריך לעשות זאת באופן ידני. מידע נוסף זמין במאמר מחיקת אוספים.

מחיקת שדות

כדי למחוק שדות ספציפיים ממסמך, משתמשים בשיטות FieldValue.delete() הספציפיות לשפה הבאה כשמעדכנים מסמך:

גרסה 9 לאינטרנט

משתמשים בשיטה deleteField():

import { doc, updateDoc, deleteField } from "firebase/firestore";

const cityRef = doc(db, 'cities', 'BJ');

// Remove the 'capital' field from the document
await updateDoc(cityRef, {
    capital: deleteField()
});

גרסה 8 לאינטרנט

משתמשים ב-method‏ FieldValue.delete():

var cityRef = db.collection('cities').doc('BJ');

// Remove the 'capital' field from the document
var removeCapital = cityRef.update({
    capital: firebase.firestore.FieldValue.delete()
});
Swift

משתמשים בשיטה FieldValue.delete():

הערה: המוצר הזה לא זמין ביעדים של watchOS ו-App Clip.
do {

  try await db.collection("cities").document("BJ").updateData([
    "capital": FieldValue.delete(),
  ])
  print("Document successfully updated")
} catch {
  print("Error updating document: \(error)")
}
Objective-C

משתמשים ב-method‏ fieldValueForDelete::

הערה: המוצר הזה לא זמין ביעדים של watchOS ו-App Clip.
[[[self.db collectionWithPath:@"cities"] documentWithPath:@"BJ"] updateData:@{
  @"capital": [FIRFieldValue fieldValueForDelete]
} completion:^(NSError * _Nullable error) {
  if (error != nil) {
    NSLog(@"Error updating document: %@", error);
  } else {
    NSLog(@"Document successfully updated");
  }
}];
Kotlin
Android

משתמשים בשיטה FieldValue.delete():

val docRef = db.collection("cities").document("BJ")

// Remove the 'capital' field from the document
val updates = hashMapOf<String, Any>(
    "capital" to FieldValue.delete(),
)

docRef.update(updates).addOnCompleteListener { }
Java
Android

משתמשים בשיטה FieldValue.delete():

DocumentReference docRef = db.collection("cities").document("BJ");

// Remove the 'capital' field from the document
Map<String,Object> updates = new HashMap<>();
updates.put("capital", FieldValue.delete());

docRef.update(updates).addOnCompleteListener(new OnCompleteListener<Void>() {
    // ...
    // ...

Dart

משתמשים בשיטה FieldValue.delete():

final docRef = db.collection("cities").doc("BJ");

// Remove the 'capital' field from the document
final updates = <String, dynamic>{
  "capital": FieldValue.delete(),
};

docRef.update(updates);
Java

משתמשים בשיטה FieldValue.delete():

DocumentReference docRef = db.collection("cities").document("BJ");
Map<String, Object> updates = new HashMap<>();
updates.put("capital", FieldValue.delete());
// Update and delete the "capital" field in the document
ApiFuture<WriteResult> writeResult = docRef.update(updates);
System.out.println("Update time : " + writeResult.get());
Python

משתמשים ב-method‏ firestore.DELETE_FIELD:

city_ref = db.collection("cities").document("BJ")
city_ref.update({"capital": firestore.DELETE_FIELD})
Python
(Async)

משתמשים ב-method‏ firestore.DELETE_FIELD:

city_ref = db.collection("cities").document("BJ")
await city_ref.update({"capital": firestore.DELETE_FIELD})
C++‎

משתמשים ב-method‏ FieldValue::Delete():

DocumentReference doc_ref = db->Collection("cities").Document("BJ");
doc_ref.Update({{"capital", FieldValue::Delete()}})
    .OnCompletion([](const Future<void>& future) { /*...*/ });
Node.js

משתמשים ב-method‏ FieldValue.delete():

// Create a document reference
const cityRef = db.collection('cities').doc('BJ');

// Remove the 'capital' field from the document
const res = await cityRef.update({
  capital: FieldValue.delete()
});
המשך

משתמשים בשיטה firestore.Delete:


import (
	"context"
	"log"

	"cloud.google.com/go/firestore"
)

func deleteField(ctx context.Context, client *firestore.Client) error {
	_, err := client.Collection("cities").Doc("BJ").Update(ctx, []firestore.Update{
		{
			Path:  "capital",
			Value: firestore.Delete,
		},
	})
	if err != nil {
		// Handle any errors in an appropriate way, such as returning them.
		log.Printf("An error has occurred: %s", err)
	}

	// ...
	return err
}
PHP

משתמשים ב-method‏ FieldValue::deleteField():

$cityRef = $db->collection('samples/php/cities')->document('BJ');
$cityRef->update([
    ['path' => 'capital', 'value' => FieldValue::deleteField()]
]);
Unity

משתמשים ב-method‏ FieldValue.Delete:

DocumentReference cityRef = db.Collection("cities").Document("BJ");
Dictionary<string, object> updates = new Dictionary<string, object>
{
    { "Capital", FieldValue.Delete }
};
C#‎

משתמשים ב-method‏ FieldValue.Delete:

DocumentReference cityRef = db.Collection("cities").Document("BJ");
Dictionary<string, object> updates = new Dictionary<string, object>
{
    { "Capital", FieldValue.Delete }
};
await cityRef.UpdateAsync(updates);
Ruby

משתמשים בשיטה firestore.field_delete:

city_ref = firestore.doc "#{collection_path}/BJ"
city_ref.update({ capital: firestore.field_delete })

מחיקת אוספים

כדי למחוק אוסף או אוסף משנה שלם ב-Firestore, צריך לאחזר (לקרוא) את כל המסמכים באוסף או באוסף המשנה ולמחוק אותם. התהליך הזה כרוך בעלויות קריאה ובעלויות מחיקה. אם יש לכם אוספים גדולים יותר, כדאי למחוק את המסמכים בקבוצות קטנות יותר כדי להימנע משגיאות שקשורות לזיכרון. חוזרים על התהליך עד שמוחקים את כל האוסף או אוסף המשנה.

כדי למחוק אוסף צריך לתאם מספר בלתי מוגבל של בקשות מחיקה נפרדות. אם אתם צריכים למחוק אוספים שלמים, עשו זאת רק מסביבת שרת מהימנה. אפשר למחוק אוסף מלקוח בנייד או באינטרנט, אבל לפעולה הזו יש השלכות שליליות על האבטחה והביצועים.

קטעי הקוד הבאים פשוטים יותר לשם הבהרה, והם לא כוללים טיפול בשגיאות, אבטחה, מחיקת אוספי משנה או אופטימיזציות של ביצועים. מידע נוסף על אחת מהגישות המומלצות למחיקת אוספים בסביבת הייצור זמין במאמר מחיקת אוספים ותתי-אוספים.

אינטרנט
// Deleting collections from a Web client is not recommended.
Swift
הערה: המוצר הזה לא זמין ביעדים של watchOS ו-App Clip.
// Deleting collections from an Apple client is not recommended.
Objective-C
הערה: המוצר הזה לא זמין ביעדים של watchOS ו-App Clip.
// Deleting collections from an Apple client is not recommended.
  
Kotlin
Android
// Deleting collections from an Android client is not recommended.
Java
Android
// Deleting collections from an Android client is not recommended.

Dart

לא מומלץ למחוק אוספים מהלקוח.

Java

import com.google.api.core.ApiFuture;
import com.google.cloud.firestore.CollectionReference;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;

public class DeleteCollection {

  /**
   * Delete a collection and all its subcollections.
   *
   * @param projectId The Google Cloud project ID
   * @param collectionName The name of the collection to delete
   */
  public static void deleteCollection(String projectId, String collectionName) throws Exception {
    FirestoreOptions firestoreOptions =
        FirestoreOptions.getDefaultInstance().toBuilder().setProjectId(projectId).build();
    try (Firestore db = firestoreOptions.getService()) {
      CollectionReference collection = db.collection(collectionName);

      ApiFuture<Void> future = db.recursiveDelete(collection);

      future.get();
      System.out.println("Collection and all its subcollections deleted successfully.");
    }
  }

  public static void main(String[] args) throws Exception {
    String projectId = "example-project-id";
    String collectionName = "example-collection-name";

    deleteCollection(projectId, collectionName);
  }
}
Python
def delete_collection(coll_ref):

    print(f"Recursively deleting collection: {coll_ref}")
    db.recursive_delete(coll_ref)
Python
(Async)
async def delete_collection(coll_ref):

    await db.recursive_delete(coll_ref)
C++‎
// This is not supported. Delete data using CLI as discussed below.
  
Node.js
async function deleteCollection(db, collectionPath) {
  const collectionRef = db.collection(collectionPath);
  return await db.recursiveDelete(collectionRef);
}
המשך

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
	"google.golang.org/api/iterator"
)

func deleteCollection(w io.Writer, projectID, collectionName string,
	batchSize int) error {

	// Instantiate a client
	ctx := context.Background()
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return err
	}

	col := client.Collection(collectionName)
	bulkwriter := client.BulkWriter(ctx)

	for {
		// Get a batch of documents
		iter := col.Limit(batchSize).Documents(ctx)
		numDeleted := 0

		// Iterate through the documents, adding
		// a delete operation for each one to the BulkWriter.
		for {
			doc, err := iter.Next()
			if err == iterator.Done {
				break
			}
			if err != nil {
				return err
			}

			bulkwriter.Delete(doc.Ref)
			numDeleted++
		}

		// If there are no documents to delete,
		// the process is over.
		if numDeleted == 0 {
			bulkwriter.End()
			break
		}

		bulkwriter.Flush()
	}
	fmt.Fprintf(w, "Deleted collection \"%s\"", collectionName)
	return nil
}
PHP
function data_delete_collection(string $projectId, string $collectionName, int $batchSize)
{
    // Create the Cloud Firestore client
    $db = new FirestoreClient([
        'projectId' => $projectId,
    ]);
    $collectionReference = $db->collection($collectionName);
    $documents = $collectionReference->limit($batchSize)->documents();
    while (!$documents->isEmpty()) {
        foreach ($documents as $document) {
            printf('Deleting document %s' . PHP_EOL, $document->id());
            $document->reference()->delete();
        }
        $documents = $collectionReference->limit($batchSize)->documents();
    }
}
Unity
// This is not supported. Delete data using CLI as discussed below.
C#‎
private static async Task DeleteCollection(CollectionReference collectionReference, int batchSize)
{
    QuerySnapshot snapshot = await collectionReference.Limit(batchSize).GetSnapshotAsync();
    IReadOnlyList<DocumentSnapshot> documents = snapshot.Documents;
    while (documents.Count > 0)
    {
        foreach (DocumentSnapshot document in documents)
        {
            Console.WriteLine("Deleting document {0}", document.Id);
            await document.Reference.DeleteAsync();
        }
        snapshot = await collectionReference.Limit(batchSize).GetSnapshotAsync();
        documents = snapshot.Documents;
    }
    Console.WriteLine("Finished deleting all documents from the collection.");
}
Ruby
cities_ref = firestore.col collection_path
query      = cities_ref

query.get do |document_snapshot|
  puts "Deleting document #{document_snapshot.document_id}."
  document_ref = document_snapshot.ref
  document_ref.delete
end

מחיקת נתונים באמצעות כללי מדיניות של TTL

מדיניות TTL מגדירה שדה מסוים כזמן התפוגה של מסמכים בקבוצת אוספים נתונה. פעולות מחיקה של TTL נכללות בעלויות של מחיקת המסמכים.

מידע נוסף על הגדרת TTL זמין במאמר ניהול שמירת הנתונים באמצעות כללי מדיניות TTL.

משימות מחיקה בכמות גדולה

ב-Firestore יש כמה כלים למחיקה בכמות גדולה. כדאי לבחור כלי בהתאם למספר המסמכים שצריך למחוק ולרמת ההגדרה הנדרשת.

למשימות קטנות יותר של אלפי מסמכים, השתמשו במסוף או ב-Firebase CLI. יכול להיות שכלים כאלה יתחילו לפעול עם פסק זמן במשימות גדולות יותר, ותצטרכו להפעיל אותם כמה פעמים.

המסוף

אפשר למחוק מסמכים ואוספים מהדף Firestore במסוף. כשמוחקים מסמך מהמסוף, כל הנתונים שמוטמעים במסמך הזה נמחקים, כולל כל אוספי המשנה.

Firebase CLI

אפשר גם להשתמש ב-Firebase CLI כדי למחוק מסמכים ואוספים. כדי למחוק נתונים, משתמשים בפקודה הבאה:

firebase firestore:delete  --database=DATABASE_ID PATH

מחליפים את DATABASE_ID במזהה מסד הנתונים ואת PATH בנתיב למסמך או לאוסף.

למשימות מחיקה גדולות (מיליוני מסמכים), השתמשו באחת מהאפשרויות הבאות:

מחיקה בכמות גדולה מנוהלת

ב-Firestore אפשר למחוק כמה קבוצות של אוספים בבת אחת. מידע נוסף זמין במאמר מחיקת נתונים בכמות גדולה.

מחבר Dataflow

אתם יכולים להשתמש ב-Dataflow כדי לבצע פעולות בכמות גדולה במסד הנתונים. זו האפשרות הכי גמישה, אבל היא גם דורשת יותר הגדרות מאפשרויות אחרות למחיקה בכמות גדולה. בפוסט בבלוג, שמציג את המחבר של Firestore ל-Dataflow, יש דוגמה למחיקת כל המסמכים בקבוצת אוספים.