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

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 を呼び出します。

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​

複数の document を batch で削除するには、collection reference で deleteMany method を使用します。deleteMany は document または document ID の array を parameter として受け取ります。

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}`);
}

複数の document を削除する場合、deleteMany は document data 全体ではなく document reference のみを必要とするため、field projectionを使用して query payload size を削減できます。

Client code
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 数を返します。

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

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

query delete では、document ID filterと通常の condition を組み合わせることができます。

Client code
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 を使用します。

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}`);
}

Error Handling​

Error原因解決策
Security rule rejectiondelete が security rules により block されたuser が collection に対する delete permission を持つことを確認する
Document not found存在しない document を削除しようとしたdocument ID が正しいこと、および document がすでに削除されていないことを確認する
Invalid pathdeleteInPath に渡した 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. 1 件ずつ loop で document を削除するのではなく、batch operation には deleteMany() を使用します。

  2. 特に batch deletion では、削除される document を確認するために、削除前に query を実行します。

    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 field を削除する場合は、document を整理された状態に保つため、null や empty value に設定するのではなく、deleteInPath() を使用します。

  4. すべての deletion をまとめて成功または失敗させる必要がある場合は、関連する delete を transaction でラップします。