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

# Collections

> Working with PocketBase collections and schemas

Collections define the structure of your data in PocketBase. Each collection has a type, fields, and various configuration options.

## Collection types

PocketBase supports three collection types:

* **base** - Standard collections for general data storage
* **auth** - Collections with built-in authentication features
* **view** - Read-only collections based on SQL queries

## Creating collections

### NewCollection()

Create a new collection with the specified type:

```go theme={null}
collection := core.NewCollection(core.CollectionTypeBase, "posts")
```

### NewBaseCollection()

Create a base collection:

```go theme={null}
collection := core.NewBaseCollection("articles")
```

### NewAuthCollection()

Create an auth collection:

```go theme={null}
users := core.NewAuthCollection("users")
```

### NewViewCollection()

Create a view collection:

```go theme={null}
view := core.NewViewCollection("posts_stats")
view.ViewQuery = "SELECT id, COUNT(*) as total FROM posts GROUP BY category"
```

## Finding collections

### FindCollectionByNameOrId()

Find a collection by name or ID:

```go theme={null}
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}
```

### FindCachedCollectionByNameOrId()

Find a collection from the app cache (faster, but read-only):

```go theme={null}
collection, err := app.FindCachedCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}
```

<Note>
  The cached collection should only be used for read-only operations. Modifying the cached collection affects the global cached value.
</Note>

### FindAllCollections()

Find all collections, optionally filtered by type:

```go theme={null}
// All collections
allCollections, err := app.FindAllCollections()

// Only auth collections
authCollections, err := app.FindAllCollections(core.CollectionTypeAuth)

// Auth and view collections
collections, err := app.FindAllCollections(
    core.CollectionTypeAuth,
    core.CollectionTypeView,
)
```

## Collection properties

### Basic properties

```go theme={null}
collection.Id          // Auto-generated ID
collection.Name        // Collection name (also the table name)
collection.Type        // base, auth, or view
collection.System      // System collection (cannot be deleted/renamed)
collection.Created     // Creation timestamp
collection.Updated     // Last update timestamp
```

### Type checking

```go theme={null}
if collection.IsBase() {
    log.Println("This is a base collection")
}

if collection.IsAuth() {
    log.Println("This is an auth collection")
}

if collection.IsView() {
    log.Println("This is a view collection")
}
```

## Managing fields

### Adding fields

```go theme={null}
collection.Fields.Add(
    &core.TextField{
        Name: "title",
        Required: true,
        Max: 200,
    },
    &core.TextField{
        Name: "content",
    },
    &core.NumberField{
        Name: "views",
        Min: types.Pointer(0.0),
    },
)
```

### Getting fields

```go theme={null}
// Get field by name
field := collection.Fields.GetByName("title")

// Get field by ID
field = collection.Fields.GetById("field_id")

// Get all field names
names := collection.Fields.FieldNames()
```

### Removing fields

```go theme={null}
collection.Fields.RemoveById("field_id")
collection.Fields.RemoveByName("old_field")
```

## API rules

Collections have API rules that control access:

```go theme={null}
// Allow anyone to list records
collection.ListRule = types.Pointer("")

// Only authenticated users can view individual records
collection.ViewRule = types.Pointer("@request.auth.id != ''")

// Only the record owner can update
collection.UpdateRule = types.Pointer("@request.auth.id = id")

// Only admins can delete
collection.DeleteRule = nil // nil means no access

// Anyone can create
collection.CreateRule = types.Pointer("")
```

<Info>
  API rules use PocketBase's filter syntax. Use `nil` to deny all access, or an empty string `""` to allow all access.
</Info>

## Auth collection options

Auth collections have additional configuration:

```go theme={null}
users := core.NewAuthCollection("users")

// Auth rule (who can authenticate)
users.AuthRule = types.Pointer("verified = true")

// OAuth2 providers
users.OAuth2.Providers = []core.OAuth2ProviderConfig{
    {
        Name: "google",
        ClientId: "your-client-id",
        ClientSecret: "your-client-secret",
        Enabled: true,
    },
}

// Password options
users.PasswordAuth.Enabled = true
users.PasswordAuth.IdentityFields = []string{"email", "username"}

// MFA options
users.MFA.Enabled = true
users.MFA.Duration = 1800 // 30 minutes

// OTP options
users.OTP.Enabled = true
users.OTP.Duration = 300 // 5 minutes
```

## View collection options

View collections are based on SQL queries:

```go theme={null}
view := core.NewViewCollection("user_stats")

view.ViewQuery = `
    SELECT
        users.id,
        users.email,
        COUNT(posts.id) as total_posts
    FROM users
    LEFT JOIN posts ON posts.user = users.id
    GROUP BY users.id
`
```

<Warning>
  View queries must include an `id` column. Wildcard columns are not supported to prevent accidentally exposing sensitive data.
</Warning>

## Indexes

### Adding indexes

```go theme={null}
// Create a unique index
collection.AddIndex(
    "idx_email",
    true, // unique
    "`email`",
    "", // no WHERE clause
)

// Create a composite index with WHERE clause
collection.AddIndex(
    "idx_active_users",
    false, // not unique
    "`status`, `created`",
    "`status` = 'active'",
)
```

### Getting indexes

```go theme={null}
idx := collection.GetIndex("idx_email")
if idx != "" {
    log.Println("Index found:", idx)
}
```

### Removing indexes

```go theme={null}
collection.RemoveIndex("idx_email")
```

## Saving collections

### Save a new collection

```go theme={null}
collection := core.NewBaseCollection("posts")

collection.Fields.Add(
    &core.TextField{Name: "title", Required: true},
    &core.TextField{Name: "content"},
)

if err := app.Save(collection); err != nil {
    log.Fatal(err)
}
```

### Update an existing collection

```go theme={null}
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}

collection.ListRule = types.Pointer("")

if err := app.Save(collection); err != nil {
    log.Fatal(err)
}
```

## Deleting collections

```go theme={null}
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
    log.Fatal(err)
}

if err := app.Delete(collection); err != nil {
    log.Fatal(err)
}
```

<Warning>
  Deleting a collection also deletes all its records and associated files.
</Warning>

## Collection references

Find all collections that reference a specific collection:

```go theme={null}
refs, err := app.FindCollectionReferences(collection)
if err != nil {
    log.Fatal(err)
}

for refCollection, fields := range refs {
    log.Printf("Collection %s references via fields:", refCollection.Name)
    for _, field := range fields {
        log.Printf("  - %s", field.GetName())
    }
}
```

## Importing collections

Import collections from configuration data:

```go theme={null}
collectionsData := []map[string]any{
    {
        "name": "posts",
        "type": "base",
        "fields": []map[string]any{
            {"name": "title", "type": "text"},
        },
    },
}

err := app.ImportCollections(collectionsData, false)
if err != nil {
    log.Fatal(err)
}
```

## Type signature

```go theme={null}
type Collection struct {
    Id         string
    Name       string
    Type       string
    System     bool
    Fields     FieldsList
    Indexes    types.JSONArray[string]
    ListRule   *string
    ViewRule   *string
    CreateRule *string
    UpdateRule *string
    DeleteRule *string
    Created    types.DateTime
    Updated    types.DateTime
}
```
