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

# Collections & Indexes

> Organize your data with collections and optimize queries with indexes

OnDB uses collections to organize data, similar to tables in traditional databases. Indexes are **required** for production use.

## Collections

Collections are logical groupings of documents:

```typescript theme={null}
import { createClient } from '@ondb/sdk';

const client = createClient({
  endpoint: 'https://api.ondb.io',
  appKey: 'your-app-key',
  appId: 'your-app-id'
});

// Create collection with schema-based indexes
await client.createCollection({
  name: 'users',
  fields: {
    email: { type: 'string', index: true, unique: true },
    createdAt: { type: 'date', index: true }
  },
  useBaseFields: true
});
```

## Why Indexes Are Required

<Warning>
  **Every collection MUST have at least one index for production use.**
</Warning>

Without indexes:

| Issue                   | Impact                                                                                                              |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Slow queries**        | All reads perform full collection scans, resulting in poor performance                                              |
| **Dashboard invisible** | The OnDB dashboard discovers collections through index configurations - collections without indexes will not appear |
| **Unoptimized costs**   | Full scans consume more resources and may cost more                                                                 |

## Index Types

### Hash Index

Best for equality lookups (e.g., `WHERE email = 'user@example.com'`):

```typescript theme={null}
await db.createIndex({
  name: 'idx_users_email',
  collection: 'users',
  field_name: 'email',
  index_type: 'hash',
  unique_constraint: true,
  store_values: true
});
```

### BTree Index

Best for range queries and sorting (e.g., `WHERE createdAt > '2024-01-01'`):

```typescript theme={null}
await db.createIndex({
  name: 'idx_users_createdAt',
  collection: 'users',
  field_name: 'createdAt',
  index_type: 'btree'
});
```

### Price Index

Special type for value-based payment models. See [PriceIndex](/payments/price-index) for details.

```typescript theme={null}
await db.createIndex({
  name: 'idx_orders_totalPrice',
  collection: 'orders',
  field_name: 'totalPrice',
  index_type: 'price'
});
```

## When to Create Indexes

<Steps>
  <Step title="Before storing data">
    Create indexes BEFORE storing any data to ensure optimal performance from the start
  </Step>

  <Step title="Query fields">
    Index all fields used in `whereField()` queries
  </Step>

  <Step title="Foreign keys">
    Index foreign key fields used in relations and JOINs
  </Step>

  <Step title="Sort fields">
    Index fields used for sorting
  </Step>
</Steps>

## Complete Example

```typescript theme={null}
import { createClient } from '@ondb/sdk';

const client = createClient({
  endpoint: 'https://api.ondb.io',
  appId: 'my-ecommerce-app',
  appKey: 'your-app-key'
});

const db = client.database('my-ecommerce-app');

// Create users collection with indexes
await client.createCollection({
  name: 'users',
  fields: {
    email: { type: 'string', index: true, unique: true },
    createdAt: { type: 'date', index: true }
  },
  useBaseFields: true
});

// Or use the database manager for individual indexes
await db.createIndex({
  name: 'idx_users_email',
  collection: 'users',
  field_name: 'email',
  index_type: 'hash',
  unique_constraint: true,
  store_values: true
});

await db.createIndex({
  name: 'idx_users_createdAt',
  collection: 'users',
  field_name: 'createdAt',
  index_type: 'btree'
});

// Create order indexes

await db.createIndex({
  name: 'idx_orders_userId',
  collection: 'orders',
  field_name: 'userId',
  index_type: 'hash'
});

await db.createIndex({
  name: 'idx_orders_status',
  collection: 'orders',
  field_name: 'status',
  index_type: 'hash'
});

// PriceIndex for payment-based pricing
await db.createIndex({
  name: 'idx_orders_totalPrice',
  collection: 'orders',
  field_name: 'totalPrice',
  index_type: 'price'
});
```

## Relations Between Collections

Create relations for better data organization:

```typescript theme={null}
const relation = await client.createRelation({
  parent_collection: 'users',
  parent_field: 'id',
  child_collection: 'posts',
  child_field: 'author_id'
});

console.log('Relation created:', relation);
console.log('Indexes created:', relation.indexes_created);
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Data Storage" icon="database" href="/concepts/data-storage">
    Store data with payment callbacks
  </Card>

  <Card title="Querying" icon="magnifying-glass" href="/querying/query-builder">
    Query your indexed collections
  </Card>
</CardGroup>
