Skip to main content

Advanced

Beta

This feature is in beta. Core behavior is stable, but some APIs or configuration may change before general availability.

Upsert, Full-Text Search, Aggregation, and Indexes.

Upsert​

Insert a new record or update an existing one (by id):

const result = await admin.db('app').table('settings').upsert({
id: 'user-preferences',
theme: 'dark',
language: 'ko',
});
// result.action → "inserted" or "updated"

Upsert by Unique Field​

By default, upsert matches by id. Use conflictTarget to match by any unique field instead:

const result = await admin.db('app').table('categories').upsert(
{ name: 'Tech', slug: 'tech', description: 'Technology posts' },
{ conflictTarget: 'slug' }
);
// If slug='tech' exists → update, otherwise → insert
// result.action → "inserted" or "updated"
note

The conflictTarget field must have a unique: true constraint in your schema. Non-unique fields will return a 400 Bad Request error. Composite unique indexes are not supported in v1.

Search across text fields using SQLite FTS5. Enable FTS in your config:

// edgebase.config.ts
databases: {
app: {
tables: {
posts: {
schema: { /* ... */ },
fts: ['title', 'content'], // Enable FTS on these fields
},
},
},
}
const results = await admin.db('app').table('posts').search('typescript tutorial').getList();
// results.items → ranked by relevance
// results.items[0].highlight → { title: "...<mark>TypeScript</mark> <mark>Tutorial</mark>..." }

Field Selection (Projection)​

You can limit which fields are returned in query results using the fields query parameter in the REST API. This reduces payload size when you only need specific columns:

GET /api/db/app/tables/posts?fields=id,title,status

This returns only id, title, and status for each record instead of all fields.

You can combine fields with all other query parameters:

GET /api/db/app/tables/posts?fields=id,title&filter=[["status","==","published"]]&sort=createdAt:desc&limit=10
note

Field selection is a REST API feature. SDK methods currently return all fields. If you need projected queries from an SDK, use raw SQL in App Functions.

Aggregation​

EdgeBase supports count() for record counting. For advanced aggregations (SUM, AVG, GROUP BY), use raw SQL in App Functions:

// functions/analytics.ts
export default defineFunction({
trigger: { type: 'http', path: '/api/functions/stats', method: 'GET' },
handler: async (context) => {
const stats = await context.admin.sql(
'posts',
'SELECT status, COUNT(*) as count FROM posts GROUP BY status',
[]
);
return Response.json(stats);
},
});

Indexes​

Defining Indexes​

posts: {
schema: { /* ... */ },
indexes: [
{ fields: ['status'] }, // Single field
{ fields: ['authorId', 'createdAt'] }, // Composite
{ fields: ['slug'], unique: true }, // Unique index
],
}

When to Add Indexes​

  • Fields frequently used in where() filters
  • Fields used in orderBy() sorting
  • Fields used as conflictTarget in upsert (must be unique)