メインコンテンツまでスキップ

データの削除

単一およびバッチの削除操作で、データベースからドキュメントまたは特定のフィールドを削除します。

Delete 操作を使う理由

ドキュメント全体の削除、複数ドキュメントの一括削除、またはドキュメントから特定フィールドの削除など、データベースからレコードを削除する必要があります。Squid Client SDK は、これら各ケースに対応する delete 操作を提供します。

概要

transaction 内で実行されない限り、すべての delete 操作は、サーバー側で mutation が適用されると resolve される Promise を返します。

他の mutation と同様に、delete はクライアントで楽観的(optimistic)に適用され、その後サーバーと同期されます。optimistic updates の仕組みの詳細は、データの追加 を参照してください。

コアコンセプト

Delete

ドキュメントを削除するには、document referencedelete メソッドを呼び出します。

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.delete();
console.log('User deleted successfully');
} catch (error) {
console.error(`Failed to delete user ${error}`);
}

Delete many

複数のドキュメントをバッチで削除するには、collection referencedeleteMany メソッドを使用します。deleteMany は、ドキュメントまたはドキュメント ID の配列をパラメータとして受け取ります。

Client code
const staleDocs = await squid
.collection<User>('users')
.query()
.eq('pending-delete', true)
.snapshot();

try {
await squid.collection<User>('users').deleteMany(staleDocs);
console.log('Users successfully deleted');
} catch (error) {
console.error(`Failed to delete users ${error}`);
}

多数のドキュメントを削除する際は、deleteMany が必要とするのはドキュメント参照であり、ドキュメントの完全なデータではないため、field projection を使用してクエリのペイロードサイズを削減できます。

Client code
const staleDocs = await squid
.collection<User>('users')
.query()
.eq('pending-delete', true)
.projectFields([])
.snapshot();

await squid.collection<User>('users').deleteMany(staleDocs);

Delete by query

ドキュメントを先に取得することなく、クエリに一致するすべてのドキュメントを削除するには、クエリで delete() を呼び出します。削除はサーバー側で実行され、削除されたドキュメント数を返します。

Client code
const { deletedCount } = await squid
.collection<User>('users')
.query()
.eq('status', 'inactive')
.delete();

console.log(`Deleted ${deletedCount} users`);

クエリによる削除では、document ID filters と通常の条件を組み合わせることができます。

Client code
await squid
.collection<User>('users')
.query()
.docIds(['user_1', 'user_2', 'user_3'])
.lte('age', 30)
.delete();

query.delete() のセマンティクスに関する注意点:

  • サーバーはバッチ単位でマッチングと削除を行い、各ドキュメントは通常の mutation パスを通ります。そのため、write security rules はすべての削除に適用され、アクティブなクエリの subscription には標準の削除イベントが届きます。
  • 選択から削除までの間にクエリへの一致がなくなったドキュメントはスキップされます。deletedCount は実際に削除されたドキュメント数を反映します。
  • sortBylimitlimitBydelete() ではサポートされておらず、エラーになります。クエリ削除で「最も古い N 件」を削除することはできません。
  • Field projection は無視され、一致したドキュメント全体が削除されます。
  • document reference の delete()deleteMany() と異なり、クエリ削除はクライアント上で楽観的に適用されません。ローカルデータは、サーバーが結果の削除イベントをプッシュしたときに更新されます。

Delete in path

ドキュメントの特定プロパティを削除するには、document reference の deleteInPath メソッドを呼び出し、削除したいプロパティへの path を渡します。path でネストされたプロパティを指定するにはドット記法を使用します。

Client code
const userRef = squid.collection<User>('users').doc('existing_user_id');

try {
await userRef.deleteInPath('contact.email');
console.log('User email deleted successfully');
} catch (error) {
console.error(`Failed to delete user email ${error}`);
}

エラーハンドリング

ErrorCauseSolution
Security rule rejectiondelete が security rules によりブロックされたユーザーが該当コレクションに対する delete 権限を持っていることを確認する
Document not found存在しないドキュメントを削除しようとしているドキュメント ID が正しいことを確認する。ドキュメントがすでに削除されていないか確認する
Invalid pathdeleteInPath に渡した path がドキュメント上に存在しないドット記法で指定した path がドキュメント構造に一致していることを確認する
query.delete() does not currently support sortBy, limit, or limitBy.クエリ削除で result-shaping modifier が使用されたsortBy/limit/limitBy を削除し、代わりに条件や document ID filter で削除対象を絞り込む

ベストプラクティス

  1. ループ内で 1 件ずつドキュメントを削除するのではなく、バッチ操作には deleteMany() を使用する

  2. 特にバッチ削除では、削除前にクエリして、どのドキュメントが削除されるかを確認する。

    Client code
    const toDelete = await squid
    .collection<User>('users')
    .query()
    .eq('status', 'inactive')
    .snapshot();
    console.log(`Deleting ${toDelete.length} inactive users`);
    await squid.collection<User>('users').deleteMany(toDelete);
  3. ドキュメントをきれいに保つため、任意(optional)フィールドを null や空の値に設定するのではなく、deleteInPath() を使って削除する

  4. すべての削除がまとめて成功または失敗することを保証したい場合は、関連する delete を transaction でラップする