> ## 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.

# Update Documents

> Update and upsert documents in OnDB

## Understanding Updates in Append-Only Storage

<Note>
  OnDB uses append-only storage. Updates do NOT modify existing data. Instead, a NEW record with the same ID and a newer timestamp is appended. Queries automatically return the latest version of each record. Use `queryBuilder().executeUnique()` to get the latest version of a single record.
</Note>

## Update Pattern

Update an existing document by finding it, modifying fields, and storing a new version.

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

if (user) {
  // Store updated version
  await client.store(
    { collection: 'users', data: [{ ...user, name: 'Alice Smith', active: false }] },
    async (quote) => {
      const txHash = await processPayment(quote);
      return { txHash, network: quote.network, sender: walletAddress, chainType: quote.chainType, paymentMethod: 'native' };
    },
    true
  );
  console.log('Updated user');
} else {
  console.log('User not found');
}
```

## How Updates Work

```
Original Record (Block 100):
{ id: "user_1", name: "Alice", email: "alice@example.com", updatedAt: "2024-01-01" }

After Update (Block 101):
{ id: "user_1", name: "Alice Smith", email: "alice@example.com", updatedAt: "2024-01-02" }

Both records are preserved, but queries return the latest version
```

## Examples

### Update Single Field

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

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

### Conditional Update Pattern

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

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

## Historical Data

Since updates append new records, you can query historical versions:

```typescript TypeScript theme={null}
const allVersions = await client.queryBuilder()
  .collection('users')
  .whereField('id').equals('user_123')
  .includeHistory()
  .execute();

// Sort by updatedAt to see history
const history = allVersions.records.sort(
  (a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Delete" icon="trash" href="/crud/delete">
    Soft delete documents
  </Card>

  <Card title="Create" icon="plus" href="/crud/create">
    Create new documents
  </Card>
</CardGroup>
