11 KiB
Collections in PocketBase
Overview
Collections are the fundamental data structures in PocketBase, similar to tables in a relational database. They define the schema and behavior of your data.
Collection Types
1. Base Collection
Flexible collection with custom schema. Used for:
- Posts, articles, products
- Comments, messages
- Any application-specific data
Characteristics:
- No built-in authentication
- Custom fields only
- Full CRUD operations
- Can be accessed via REST API
2. Auth Collection
Special collection for user accounts. Used for:
- User registration and login
- User profiles and settings
- Authentication workflows
Characteristics:
- Built-in auth fields (
email,password,emailVisibility,verified) - Automatic user ID tracking on creation
- OAuth2 support
- Password management
- Email verification
- Password reset functionality
3. View Collection
Read-only collection based on SQL views. Used for:
- Complex joins and aggregations
- Denormalized data for performance
- Reporting and analytics
- Dashboard metrics
Characteristics:
- Read-only (no create, update, delete)
- Defined via SQL query
- Auto-updates when source data changes
- Useful for performance optimization
Creating Collections
Via Admin UI
- Navigate to Collections
- Click "New Collection"
- Choose collection type
- Configure name and schema
- Save
Via API
const collection = await pb.collections.create({
name: 'products',
type: 'base',
schema: [
{
name: 'name',
type: 'text',
required: true
},
{
name: 'price',
type: 'number',
required: true
}
]
});
Schema Field Types
Text
Short to medium text strings.
{
"name": "title",
"type": "text",
"options": {
"min": null,
"max": null,
"pattern": ""
}
}
Options:
min- Minimum character lengthmax- Maximum character lengthpattern- Regex pattern for validation
Number
Integer or decimal numbers.
{
"name": "price",
"type": "number",
"options": {
"min": null,
"max": null,
"noDecimal": false
}
}
Options:
min- Minimum valuemax- Maximum valuenoDecimal- Allow only integers
Email addresses with validation.
{
"name": "contact_email",
"type": "email"
}
URL
URLs with validation.
{
"name": "website",
"type": "url"
}
Date
Date and time values.
{
"name": "published_date",
"type": "date",
"options": {
"min": "",
"max": ""
}
}
Boolean
True/false values.
{
"name": "is_published",
"type": "bool"
}
JSON
Arbitrary JSON data.
{
"name": "metadata",
"type": "json"
}
Relation
Links to records in other collections.
{
"name": "author",
"type": "relation",
"options": {
"collectionId": "AUTH_COLLECTION_ID",
"cascadeDelete": false,
"maxSelect": 1,
"displayFields": null
}
}
Options:
collectionId- Target collection IDcascadeDelete- Delete related records when this is deletedmaxSelect- Maximum number of related records (1 or null for unlimited)displayFields- Fields to display when showing the relation
File
File uploads and storage.
{
"name": "avatar",
"type": "file",
"options": {
"maxSelect": 1,
"maxSize": 5242880,
"mimeTypes": ["image/*"],
"thumbs": ["100x100", "300x300"]
}
}
Options:
maxSelect- Maximum number of filesmaxSize- Maximum file size in bytesmimeTypes- Allowed MIME types (array or ["*"] for all)thumbs- Auto-generate image thumbnails at specified sizes
Select
Dropdown with predefined options.
{
"name": "status",
"type": "select",
"options": {
"values": ["draft", "published", "archived"],
"maxSelect": 1
}
}
Options:
values- Array of allowed valuesmaxSelect- Maximum selections (1 for single select, null for multi-select)
Autodate
Automatically populated dates.
{
"name": "created",
"type": "autodate",
"options": {
"onCreate": true,
"onUpdate": false
}
}
Options:
onCreate- Set on record creationonUpdate- Update on record modification
Username
Unique usernames (valid only for auth collections).
{
"name": "username",
"type": "username",
"options": {
"min": 3,
"max": null
}
}
Collection Rules
Rules control who can access, create, update, and delete records.
Types of Rules
- List Rule - Who can list/view multiple records
- View Rule - Who can view individual records
- Create Rule - Who can create new records
- Update Rule - Who can modify records
- Delete Rule - Who can delete records
Rule Syntax
Authenticated Users Only
@request.auth.id != ""
Owner-Based Access
user_id = @request.auth.id
Role-Based Access
@request.auth.role = 'admin'
Conditional Access
status = 'published' || @request.auth.id = author_id
Complex Conditions
@request.auth.role = 'moderator' && @request.auth.verified = true
Special Variables
@request.auth- Current authenticated user@request.auth.id- User ID@request.auth.email- User email@request.auth.role- User role@request.auth.verified- Email verification status
Rule Examples
Public Blog Posts
List Rule: status = 'published'
View Rule: status = 'published'
Create Rule: @request.auth.id != ''
Update Rule: author_id = @request.auth.id
Delete Rule: author_id = @request.auth.id
Private User Data
List Rule: user_id = @request.auth.id
View Rule: user_id = @request.auth.id
Create Rule: @request.auth.id != ''
Update Rule: user_id = @request.auth.id
Delete Rule: user_id = @request.auth.id
Admin-Only Content
List Rule: @request.auth.role = 'admin'
View Rule: @request.auth.role = 'admin'
Create Rule: @request.auth.role = 'admin'
Update Rule: @request.auth.role = 'admin'
Delete Rule: @request.auth.role = 'admin'
Moderated Comments
List Rule: status = 'approved' || author_id = @request.auth.id
View Rule: status = 'approved' || author_id = @request.auth.id
Create Rule: @request.auth.id != ''
Update Rule: author_id = @request.auth.id
Delete Rule: author_id = @request.auth.id || @request.auth.role = 'moderator'
Collection Indexes
Indexes improve query performance on frequently searched or sorted fields.
Creating Indexes
Via Admin UI
- Go to collection settings
- Click "Indexes" tab
- Click "New Index"
- Select fields to index
- Save
Via API
await pb.collections.update('COLLECTION_ID', {
indexes: [
'CREATE INDEX idx_posts_status ON posts(status)',
'CREATE INDEX idx_posts_author ON posts(author_id)',
'CREATE INDEX idx_posts_created ON posts(created)'
]
});
Index Best Practices
-
Index fields used in filters
CREATE INDEX idx_posts_status ON posts(status) -
Index fields used in sorts
CREATE INDEX idx_posts_created ON posts(created) -
Index foreign keys (relations)
CREATE INDEX idx_comments_post ON comments(post_id) -
Composite indexes for multi-field queries
CREATE INDEX idx_posts_status_created ON posts(status, created) -
Don't over-index - Each index adds overhead to writes
Collection Options
General Options
- Name - Collection identifier (used in API endpoints)
- Type - base, auth, or view
- System collection - Built-in collections (users, pb_users_auth)
- List encryption - Encrypt data in list views
API Options
- API keys - Manage read/write API keys
- CRUD endpoints - Enable/disable specific endpoints
- File access - Configure public/private file access
Auth Collection Options
- Min password length - Minimum password requirements
- Password constraints - Require uppercase, numbers, symbols
- Email verification - Require email confirmation
- OAuth2 providers - Configure social login
Managing Collections
List Collections
const collections = await pb.collections.getList(1, 50);
Get Collection
const collection = await pb.collections.getOne('COLLECTION_ID');
Update Collection
const updated = await pb.collections.update('COLLECTION_ID', {
name: 'new_name',
schema: [
// updated schema
]
});
Delete Collection
await pb.collections.delete('COLLECTION_ID');
Export Collection Schema
const collection = await pb.collections.getOne('COLLECTION_ID');
const schemaJSON = JSON.stringify(collection.schema, null, 2);
Best Practices
-
Plan Schema Carefully
- Design before implementing
- Consider future needs
- Use appropriate field types
-
Use Relations Wisely
- Normalize data appropriately
- Set cascadeDelete when appropriate
- Consider performance impact
-
Set Rules Early
- Security from the start
- Test rules thoroughly
- Document rule logic
-
Index Strategically
- Profile slow queries
- Index commonly filtered fields
- Avoid over-indexing
-
Use Auth Collections for Users
- Built-in auth features
- OAuth2 support
- Password management
-
Use Views for Complex Queries
- Improve performance
- Simplify frontend code
- Pre-compute expensive joins
Common Patterns
Blog/Post System
Collections:
- posts (base) - title, content, author, status, published_date
- categories (base) - name, slug, description
- tags (base) - name, slug
- posts_tags (base) - post_id, tag_id (relation join)
E-commerce
Collections:
- products (base) - name, price, description, category, stock
- orders (base) - user, items, total, status
- order_items (base) - order, product, quantity, price
- categories (base) - name, parent (self-relation)
Social Network
Collections:
- posts (base) - author, content, media, created, visibility
- likes (base) - post, user (unique constraint)
- follows (base) - follower, following (unique constraint)
- users (auth) - built-in auth + profile fields
Troubleshooting
Collection not showing data
- Check listRule
- Verify user permissions
- Check if view collection is properly configured
Slow queries
- Add database indexes
- Optimize rule conditions
- Use views for complex joins
Can't create records
- Check createRule
- Verify required fields
- Ensure user is authenticated
File uploads failing
- Check maxSize and mimeTypes
- Verify file field options
- Check user has create permissions
Related Topics
- Authentication - User management
- API Rules & Filters - Security rules syntax
- Working with Relations - Field relationships
- Files Handling - File uploads and storage
- Schema Templates - Pre-built schemas