Data の削除
単一および batch delete operation を使用して、database から document または特定の field を削除します。
Delete Operation を使用する理由
document 全体の削除、複数 document の一括削除、document の特定 field の削除など、database から record を削除する必要があります。Squid Client SDK は、これらの各ケースに対応する delete operation を提供します。
概要
transaction 内で実行される場合を除き、すべての delete operation は、server で mutation が適用されると resolve する Promise を返します。
他の mutation と同様に、delete は client に optimistic に適用され、その後 server と sync されます。optimistic update の仕組みについては、Adding dataを参照してください。
コアコンセプト
Delete
document を削除するには、document reference で delete method を呼び出します。
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
複数の document を batch で削除するには、collection reference で deleteMany method を使用します。deleteMany は document または document ID の array を parameter として受け取ります。
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}`);
}
複数の document を削除する場合、deleteMany は document data 全体ではなく document reference のみを必要とするため、field projectionを使用して query payload size を削減できます。
const staleDocs = await squid
.collection<User>('users')
.query()
.eq('pending-delete', true)
.projectFields([])
.snapshot();
await squid.collection<User>('users').deleteMany(staleDocs);
Query による Delete
最初に document を fetch せずに query に一致するすべての document を削除するには、query で delete() を呼び出します。削除は server-side で実行され、削除された document 数を返します。
const { deletedCount } = await squid
.collection<User>('users')
.query()
.eq('status', 'inactive')
.delete();
console.log(`Deleted ${deletedCount} users`);
query delete では、document ID filterと通常の condition を組み合わせることができます。
await squid
.collection<User>('users')
.query()
.docIds(['user_1', 'user_2', 'user_3'])
.lte('age', 30)
.delete();
query.delete() の semantics に関する注記:
- server は batch で match と delete を行い、各 document は通常の mutation path を通過します。そのため、各 delete にはwrite security rulesが適用され、active query subscription は標準の delete event を受け取ります。
- selection と deletion の間に document が query に一致しなくなった場合、その document は skip されます。したがって、
deletedCountは実際に削除された document を反映します。 sortBy、limit、limitByはdelete()ではサポートされず、error を throw します。query delete では「最も古い N 件」を削除することはできません。- field projection は無視されます。一致する document 全体が削除されます。
- document reference の
delete()およびdeleteMany()とは異なり、query delete は client に optimistic に適用されません。local data は、server が結果の delete event を push した時点で更新されます。
Path 内の Delete
document の特定 property を削除するには、document reference で deleteInPath method を呼び出し、削除する property の path を渡します。path 内の nested property を指定するには dot notation を使用します。
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}`);
}
Error Handling
| Error | 原因 | 解決策 |
|---|---|---|
| Security rule rejection | delete が security rules により block された | user が collection に対する delete permission を持つことを確認する |
| Document not found | 存在しない document を削除しようとした | document ID が正しいこと、および document がすでに削除されていないことを確認する |
| Invalid path | deleteInPath に渡した path が document に存在しない | dot notation を使用した path が document structure と一致していることを確認する |
query.delete() does not currently support sortBy, limit, or limitBy. | query delete に result-shaping modifier が使用された | sortBy/limit/limitBy を削除し、代わりに condition または document ID filter で deletion を絞り込む |
ベストプラクティス
-
1 件ずつ loop で document を削除するのではなく、batch operation には
deleteMany()を使用します。 -
特に batch deletion では、削除される document を確認するために、削除前に query を実行します。
Client codeconst 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); -
optional field を削除する場合は、document を整理された状態に保つため、
nullや empty value に設定するのではなく、deleteInPath()を使用します。 -
すべての deletion をまとめて成功または失敗させる必要がある場合は、関連する delete を transaction でラップします。