Database
The Database service provides a document query API. Write queries once and the platform handles everything — your code works identically in development and production.
import { getPlatform } from '@maravilla-labs/platform';
const platform = getPlatform();
await platform.env.DB.insertOne('users', { name: 'Alice', age: 30 });
const user = await platform.env.DB.findOne('users', { name: 'Alice' });
API Reference
find(collection, filter?, options?)
Finds multiple documents matching a filter.
Parameters:
collection(string) — the collection namefilter(object, optional) — document query filteroptions(object, optional):sort(object) — field-to-direction map (1for ascending,-1for descending)limit(number) — maximum documents to return (default/max: 1000)skip(number) — number of documents to skip
Returns: an array of matching documents.
const users = await platform.env.DB.find('users', { active: true }, {
sort: { createdAt: -1 },
limit: 20,
skip: 0
});
findOne(collection, filter)
Finds a single document matching the filter. Returns the document or null.
const user = await platform.env.DB.findOne('users', {
email: 'alice@example.com'
});
insertOne(collection, doc)
Inserts a single document. Returns the generated document ID as a string.
const id = await platform.env.DB.insertOne('users', {
name: 'Alice',
email: 'alice@example.com',
age: 30,
tags: ['premium', 'early-adopter']
});
console.log(id); // generated document ID string
updateOne(collection, filter, update)
Updates a single document matching the filter. Supports update operators.
// Simple field replacement
await platform.env.DB.updateOne('users',
{ email: 'alice@example.com' },
{ age: 31, lastLogin: Date.now() }
);
// Using update operators
await platform.env.DB.updateOne('users',
{ email: 'alice@example.com' },
{ $set: { status: 'inactive' }, $inc: { loginCount: 1 } }
);
deleteOne(collection, filter)
Deletes a single document matching the filter.
await platform.env.DB.deleteOne('users', {
email: 'alice@example.com'
});
Query Operators
Comparison Operators
// $eq -- equals (implicit or explicit)
await platform.env.DB.find('users', { age: 30 }); // implicit
await platform.env.DB.find('users', { age: { $eq: 30 } }); // explicit
// $ne -- not equals
await platform.env.DB.find('users', { status: { $ne: 'deleted' } });
// $gt -- greater than
await platform.env.DB.find('products', { price: { $gt: 100 } });
// $gte -- greater than or equal
await platform.env.DB.find('users', { age: { $gte: 18 } });
// $lt -- less than
await platform.env.DB.find('products', { stock: { $lt: 10 } });
// $lte -- less than or equal
await platform.env.DB.find('users', { score: { $lte: 100 } });
// Combining operators on the same field
await platform.env.DB.find('products', {
price: { $gte: 50, $lte: 200 } // between 50 and 200
});
Array/Set Operators
// $in -- value matches any element in the array
await platform.env.DB.find('users', {
status: { $in: ['active', 'premium', 'vip'] }
});
// $nin -- value does not match any element
await platform.env.DB.find('users', {
role: { $nin: ['admin', 'moderator'] }
});
Logical Operators
// $or -- matches if any condition is true
await platform.env.DB.find('products', {
$or: [
{ category: 'electronics' },
{ price: { $lt: 20 } }
]
});
// $and -- matches if all conditions are true (explicit)
await platform.env.DB.find('users', {
$and: [
{ age: { $gte: 18 } },
{ status: 'active' }
]
});
// Implicit $and -- multiple fields in a single filter
await platform.env.DB.find('users', {
age: { $gte: 18 },
status: 'active',
verified: true
});
Element Operators
// $exists -- check if a field exists
await platform.env.DB.find('users', {
email: { $exists: true } // documents that have an email field
});
await platform.env.DB.find('users', {
phone: { $exists: false } // documents without a phone field
});
String Operators
// $regex -- pattern matching
await platform.env.DB.find('users', {
email: { $regex: '.*@company.com' }
});
Array Operators
// $size -- match arrays of a specific length
await platform.env.DB.find('posts', {
tags: { $size: 3 } // posts with exactly 3 tags
});
Update Operators
Use these with updateOne to perform targeted modifications instead of replacing entire documents.
$set — Set Field Values
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $set: { status: 'inactive', updatedAt: Date.now() } }
);
$unset — Remove Fields
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $unset: { temporaryFlag: '' } }
);
$inc — Increment Numeric Values
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $inc: { loginCount: 1, score: 5 } }
);
$push — Add to Array
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $push: { tags: 'verified' } }
);
$pull — Remove from Array
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $pull: { tags: 'unverified' } }
);
$addToSet — Add to Array (No Duplicates)
await platform.env.DB.updateOne('users',
{ id: '123' },
{ $addToSet: { tags: 'premium' } } // only adds if not already present
);
Complex Query Examples
Pagination
const pageSize = 20;
const pageNumber = 2;
const results = await platform.env.DB.find('users',
{ active: true },
{
sort: { createdAt: -1 },
limit: pageSize,
skip: pageSize * (pageNumber - 1)
}
);
Compound Filters
// Find adult users in specific cities with premium status
const premiumAdults = await platform.env.DB.find('users', {
age: { $gte: 18 },
city: { $in: ['New York', 'Los Angeles', 'Chicago'] },
status: 'premium',
active: true
});
Nested Logical Operators
// Cheap products OR highly-rated electronics in stock
const products = await platform.env.DB.find('products', {
$or: [
{ price: { $lt: 20 } },
{
$and: [
{ category: 'electronics' },
{ rating: { $gte: 4.5 } },
{ inStock: true }
]
}
]
});
Optional Field Queries
// Users with no email field, or with a verified email
const users = await platform.env.DB.find('users', {
$or: [
{ email: { $exists: false } },
{ emailVerified: true }
]
});
Tenant Isolation
All queries are automatically scoped to the current tenant. You never need to manage tenant IDs manually:
// You write:
await platform.env.DB.find('users', { active: true });
// The platform executes:
// { active: true, _tenant_id: "current-tenant-id" }
Cross-tenant data access is not possible through the API.
Type Handling
The platform correctly handles all standard JavaScript types:
| JavaScript Type | Supported |
|---|---|
| String | Yes |
| Number | Yes |
| Boolean | Yes |
| Object | Yes |
| Array | Yes |
| null | Yes |
Best Practices
- Write queries once — your code runs in any environment
- Leverage query operators — use
$gte,$in, etc. instead of fetching all documents and filtering in JavaScript - Always use
limit— avoid unbounded queries on large collections - Batch reads with
find— use filters instead of multiplefindOnecalls - Use
$setfor partial updates — avoid overwriting entire documents when updating a few fields
Limits
| Parameter | Value |
|---|---|
| Max documents per query | 1,000 |
| Automatic indexing | _tenant_id on every collection |
Next Steps
- Platform Services Overview — how all three services fit together
- KV Store API Reference — for simple key-value storage
- Storage API Reference — for file and object storage