> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ondb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Delete Documents

> Soft delete documents in OnDB

## Understanding Deletes in Append-Only Storage

<Note>
  OnDB performs **soft deletes**. When you delete a document, a new record with `deleted: true` is appended. The original data is preserved but excluded from query results by default.
</Note>

## Delete Pattern

Soft delete a document by finding it and storing a new version with `deleted: true`.

```typescript TypeScript theme={null}
// Find the document
const user = await client.queryBuilder()
  .collection('users')
  .whereField('email').equals('alice@example.com')
  .executeUnique();

if (user) {
  // Store soft-deleted version
  await client.store(
    { collection: 'users', data: [{ ...user, deleted: true, deletedAt: new Date().toISOString() }] },
    async (quote) => {
      const txHash = await processPayment(quote);
      return { txHash, network: quote.network, sender: walletAddress, chainType: quote.chainType, paymentMethod: 'native' };
    },
    true
  );
  console.log('Deleted user');
} else {
  console.log('User not found');
}
```

## How Deletes Work

```
Original Record (Block 100):
{ id: "user_1", name: "Alice", email: "alice@example.com", deleted: false }

After Delete (Block 101):
{ id: "user_1", deleted: true, deletedAt: "2024-01-02", updatedAt: "2024-01-02" }

Original record is preserved, but queries exclude deleted records
```

## Examples

### Delete by ID

```typescript TypeScript theme={null}
const post = await client.queryBuilder()
  .collection('posts')
  .whereField('id').equals('post_123')
  .executeUnique();

if (post) {
  await client.store(
    { collection: 'posts', data: [{ ...post, deleted: true, deletedAt: new Date().toISOString() }] },
    paymentCallback,
    true
  );
  console.log('Post deleted successfully');
} else {
  console.log('Post not found');
}
```

### Conditional Delete Pattern

```typescript TypeScript theme={null}
// First verify ownership or permissions
const post = await client.queryBuilder()
  .collection('posts')
  .whereField('id').equals('post_123')
  .executeUnique();

if (post && post.author === currentUser.id) {
  await client.store(
    { collection: 'posts', data: [{ ...post, deleted: true, deletedAt: new Date().toISOString() }] },
    paymentCallback,
    true
  );
  console.log('Post deleted');
} else {
  console.log('Unauthorized or not found');
}
```

## Verifying Deletion

After deletion, the document won't appear in normal queries:

```typescript TypeScript theme={null}
// Delete a user
const user = await client.queryBuilder()
  .collection('users')
  .whereField('id').equals('user_123')
  .executeUnique();

if (user) {
  await client.store(
    { collection: 'users', data: [{ ...user, deleted: true, deletedAt: new Date().toISOString() }] },
    paymentCallback,
    true
  );
}

// executeUnique returns null for deleted documents
const deleted = await client.queryBuilder()
  .collection('users')
  .whereField('id').equals('user_123')
  .executeUnique();
console.log(deleted); // null
```

## Data Retention

Since OnDB uses append-only storage:

| Aspect            | Behavior                                |
| ----------------- | --------------------------------------- |
| **Original data** | Remains on blockchain permanently       |
| **Query results** | Exclude deleted records by default      |
| **Audit trail**   | Full history is preserved               |
| **Recovery**      | Possible by querying historical records |

## Bulk Delete Pattern

For deleting multiple documents, query and delete each:

```typescript TypeScript theme={null}
const result = await client.queryBuilder()
  .collection('users')
  .whereField('active').isFalse()
  .execute();

for (const user of result.records) {
  await client.store(
    { collection: 'users', data: [{ ...user, deleted: true, deletedAt: new Date().toISOString() }] },
    paymentCallback,
    true
  );
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="CRUD Overview" icon="database" href="/crud/overview">
    Back to CRUD overview
  </Card>

  <Card title="Query Builder" icon="magnifying-glass" href="/querying/query-builder">
    Complex queries
  </Card>
</CardGroup>
