Skip to main content

JSON

Ormed has first-class JSON support across models and query builder APIs.

Prerequisites

What You’ll Learn

  • How to query JSON fields with helper and selector syntax
  • How JSON indexing and path semantics behave
  • How to update JSON payloads through query and model workflows

Step Outcome

By the end of this page, you should be able to map JSON columns, filter by JSON paths, and apply partial JSON updates without replacing full documents.

Ormed supports:

  • JSON fields on models via casts/codecs
  • JSON path filters via whereJson* helpers
  • JSON selector syntax with -> / ->>
  • JSON path/patch updates from query and tracked-model APIs
note

These examples focus on JSON operations only. They assume you already have a working DataSource.

1. Define JSON Model Fields

(table: 'users')
class User extends Model<User> {
const User({required this.id, required this.email, this.metadata});

(isPrimaryKey: true, autoIncrement: true)
final int id;

final String email;

// Use the built-in `json` cast key for JSON objects.
(cast: 'json')
final Map<String, Object?>? metadata;
}

2. Query JSON Data

In Dart strings, $ is interpolation — if you write selectors with $.path, use raw strings (r'...'), or omit the $ prefix (metadata->>mode).

Array indexes can be addressed as either:

  • items[0] (explicit), or
  • items.0 (shorthand; normalized to items[0])

If you need a numeric object key, use bracket quoting: items["0"].

Future<List<User>> jsonWhereHelpers(DataSource dataSource) {
return dataSource
.query<$User>()
.whereJsonContains('metadata', 'Dart', path: r'$.skills')
.whereJsonContainsKey('metadata', r'$.flags')
.whereJsonLength('metadata->tags', '>=', 2)
.whereJsonOverlaps('metadata->skills', ['Dart', 'Go'])
.get();
}

3. Update JSON Values

Future<void> jsonUpdateQuery(DataSource dataSource) async {
await dataSource.query<$User>().whereEquals('id', 1).update(
{'email': 'updated@example.com'},
jsonUpdates: (_) => [
JsonUpdateDefinition.path('metadata', r'$.meta.count', 5),
JsonUpdateDefinition.selector('metadata->mode', 'light'),
// Update JSON array elements (both forms normalize the same way).
JsonUpdateDefinition.path(
'metadata',
r'$.meta.profile.items[1].label',
'b2',
),
JsonUpdateDefinition.path(
'metadata',
r'$.meta.profile.items.0.label',
'a2',
),
JsonUpdateDefinition.patch('metadata', {
'flags': {'beta': true},
}),
],
);
}

Practical Rules

  • Use helper methods (whereJsonContains, whereJsonLength, whereJsonContainsKey) for portability and readability.
  • Use raw selector syntax for advanced expressions or mixed SQL/JSON predicates.
  • Prefer path/patch updates over full document replacement to reduce write size.

Verify Your Setup

  • JSON model fields round-trip through your driver.
  • JSON selector filters return expected rows for both object keys and array indexes.
  • Partial JSON updates preserve unrelated keys.

Read This Next