Creating Documents
Learn how to create and insert documents into CosmosDB with CosmosQL
Complete guide to inserting documents into CosmosDB.
Navigation:
- Single Document - Basic create operations
- Bulk Operations - Creating multiple documents
- Default Values - Using schema defaults
Single Document
Use when: Creating one document at a time.
Example scenario: User registration.
const newUser = await db.users.create({
data: {
id: 'user_123',
email: 'john@example.com',
name: 'John Doe',
age: 30,
createdAt: new Date()
// Optional fields with defaults are automatically applied
}
});
// Returns: Fully typed User objectWhat happens:
- CosmosQL generates a POST request to CosmosDB REST API
- Document is stored in the partition determined by
email - Return value is fully typed based on your schema
Cost: ~5 RU per document
Default Values
Use when: Your schema defines defaults for optional fields.
const users = container('users', {
id: field.string(),
email: field.string(),
isActive: field.boolean().default(true), // Default value
createdAt: field.date()
}).partitionKey('email');
// No need to provide isActive
const user = await db.users.create({
data: {
id: 'user_123',
email: 'john@example.com',
createdAt: new Date()
// isActive automatically true
}
});Bulk Operations
Use when: Creating multiple documents in one request.
Requirement: All documents MUST share the same partition key.
Why: CosmosDB batch operations only work within a single partition.
Example scenario: Importing user posts.
await db.posts.createMany({
data: [
{ id: 'post_1', userId: 'user_123', title: 'First', content: '...' },
{ id: 'post_2', userId: 'user_123', title: 'Second', content: '...' },
{ id: 'post_3', userId: 'user_123', title: 'Third', content: '...' }
],
partitionKey: 'user_123' // Must be same for all documents
});Cost: ~5 RU per document (same as single creates)
Performance: Single HTTP request vs multiple
Error handling: If any document fails, none are created (atomic within partition).
Best Practices
1. Always Provide IDs Explicitly
// ✅ Good: Explicit ID
const user = await db.users.create({
data: {
id: `user_${Date.now()}`, // Predictable
email: 'user@example.com',
// ...
}
});2. Use Meaningful IDs
// ✅ Good: Human-readable
'user_john@example.com'
'order_2024-01-15-abc123'
// ❌ Bad: Random UUIDs (unless you need them)
'a3f5b8c2-d4e6-7890-abcd-ef1234567890'3. Set Timestamps Explicitly
const user = await db.users.create({
data: {
id: 'user_123',
email: 'john@example.com',
createdAt: new Date(), // Server time
updatedAt: new Date()
}
});Error Handling
try {
const user = await db.users.create({
data: {
id: 'user_123',
email: 'john@example.com',
// ...
}
});
} catch (error) {
if (error.code === 409) {
// Document with this ID already exists
console.error('User already exists');
} else if (error.code === 429) {
// Rate limit exceeded
console.error('Rate limit exceeded, please retry');
} else {
console.error('Failed to create user:', error);
}
}Common Patterns
Pattern: Multi-Tenant Applications
// Partition by tenant ID
const posts = container('posts', {
id: field.string(),
tenantId: field.string(),
title: field.string(),
// ...
}).partitionKey('tenantId');
// Create posts scoped to a tenant
await db.posts.createMany({
data: [
{ id: 'post_1', tenantId: 'tenant_abc', title: '...' },
{ id: 'post_2', tenantId: 'tenant_abc', title: '...' }
],
partitionKey: 'tenant_abc'
});Pattern: Hierarchical Data
// Create parent-child relationships
const category = await db.categories.create({
data: {
id: 'cat_tech',
name: 'Technology',
parentId: null,
createdAt: new Date()
}
});
const subcategory = await db.categories.create({
data: {
id: 'cat_tech_ai',
name: 'Artificial Intelligence',
parentId: 'cat_tech',
createdAt: new Date()
}
});Next Steps
- Read Reading Documents to learn efficient query patterns
- See Common Patterns for real-world scenarios
- Review Update Operations for modifying documents