Skip to content

Template Expressions

Template expressions allow you to dynamically evaluate and transform data using expressions, string interpolation, and field references.

Overview

Template Expressions - Powerful expression syntax for dynamic data transformation. Use templates to combine fields, evaluate expressions, and format output in both mutation operations and output expressions.

Where template expressions are used:

  • Mutations - Transform data in db.update, db.upsert, db.insert operations
  • Output Expressions - Format and transform query results in db.find

Template syntax:

json
{
  "greeting": "Hello {{ first_name }}!",
  "count": "{{ @random() }}",
  "score": "?{{ points * 2 }}",
  "$full_name": "first_name + ' ' + last_name"
}

Expression Syntax

{{ }} - String Template

Evaluates expression and returns result as a string. Supports string interpolation.

json
{
  "greeting": "Hello {{ first_name }}!",
  "message": "You have {{ item_count }} items",
  "full_text": "{{ title }} - {{ description }}"
}

Characteristics:

  • Always returns string type
  • Supports multiple expressions in one string
  • Ideal for text formatting and concatenation

Example:

json
{
  "op": "db.update",
  "collection": "users",
  "filter": { "_key": "user_123" },
  "data": {
    "display_text": "User {{ name }} has {{ points }} points"
  }
}

Result:

"User John Doe has 150 points"

?{{ }} - Native Type Evaluation

Evaluates expression and returns result in its native data type (number, boolean, object, array).

json
{
  "score": "?{{ points * 2 }}",
  "is_active": "?{{ login_count > 0 }}",
  "total": "?{{ price + tax }}",
  "random_number": "?{{ @random() }}"
}

Characteristics:

  • Returns native type (number, boolean, object, array)
  • Cannot combine with string interpolation
  • Use for mathematical operations and type-specific values

Example:

json
{
  "op": "db.update",
  "collection": "orders",
  "filter": { "_key": "order_123" },
  "data": {
    "total": "?{{ subtotal + tax }}",
    "is_eligible": "?{{ total >= 100 }}",
    "discount_amount": "?{{ total * 0.1 }}"
  }
}

Result:

json
{
  "total": 125.50,
  "is_eligible": true,
  "discount_amount": 12.55
}

$ Prefix - Shorthand Expressions

Shorthand syntax for simple expressions. Equivalent to {{ expression }}.

json
{
  "$full_name": "first_name + ' ' + last_name",
  "$item_count": "@len(items)",
  "$display_price": "price + ' USD'"
}

Characteristics:

  • Prefix field name with $
  • No need for {{ }} brackets
  • Cleaner syntax for simple expressions

Example:

json
{
  "op": "db.update",
  "collection": "users",
  "filter": { "_key": "user_123" },
  "data": {
    "$full_name": "first_name + ' ' + last_name",
    "$age_group": "age >= 18 ? 'adult' : 'minor'"
  }
}

Equivalent to:

json
{
  "full_name": "{{ first_name + ' ' + last_name }}",
  "age_group": "{{ age >= 18 ? 'adult' : 'minor' }}"
}

Field References

Access document fields directly by name:

json
{
  "message": "Hello {{ name }}",
  "info": "{{ email }} - {{ phone }}",
  "$total": "price + shipping"
}

Nested fields use dot notation:

json
{
  "address_line": "{{ address.street }}, {{ address.city }}",
  "$user_name": "user.profile.name"
}

String Interpolation

Combine multiple expressions and static text:

json
{
  "welcome": "Welcome {{ first_name }} {{ last_name }}!",
  "summary": "Order #{{ order_id }} - {{ item_count }} items - ${{ total }}",
  "status": "User {{ name }} ({{ role }}) logged in at {{ login_time }}"
}

Multiple expressions:

json
{
  "op": "db.update",
  "collection": "notifications",
  "filter": { "_key": "notif_123" },
  "data": {
    "message": "{{ user_name }} purchased {{ product_name }} for ${{ price }}"
  }
}

Mathematical Operations

Use expressions for calculations:

Basic math:

json
{
  "total": "?{{ price * quantity }}",
  "discount": "?{{ total * 0.1 }}",
  "final_price": "?{{ total - discount }}"
}

Compound expressions:

json
{
  "op": "db.update",
  "collection": "orders",
  "filter": { "_key": "order_123" },
  "data": {
    "tax": "?{{ subtotal * 0.08 }}",
    "shipping": "?{{ weight * 2.5 }}",
    "total": "?{{ subtotal + (subtotal * 0.08) + (weight * 2.5) }}"
  }
}

Conditional Expressions

Ternary operator for conditional values:

json
{
  "status": "{{ age >= 18 ? 'adult' : 'minor' }}",
  "shipping": "?{{ total >= 50 ? 0 : 9.99 }}",
  "badge": "{{ points > 1000 ? 'gold' : points > 500 ? 'silver' : 'bronze' }}"
}

Example:

json
{
  "op": "db.update",
  "collection": "users",
  "filter": { "_key": "user_123" },
  "data": {
    "membership": "{{ points >= 1000 ? 'premium' : 'standard' }}",
    "discount_rate": "?{{ is_vip ? 0.2 : 0.1 }}",
    "$status_text": "active ? 'Active User' : 'Inactive User'"
  }
}

Helper Functions

Template expressions support helper functions prefixed with @:

json
{
  "uuid": "{{ @uuid() }}",
  "random": "?{{ @random() }}",
  "timestamp": "?{{ @now() }}",
  "item_count": "?{{ @len(items) }}"
}

Common helpers:

  • @uuid() - Generate UUID
  • @random() - Random number
  • @now() - Current timestamp
  • @len(field) - Get length/count
  • @upper(field) - Uppercase
  • @lower(field) - Lowercase

See Helper Functions for complete reference.


Usage in Mutations

Template expressions in data object for updates and inserts:

Basic Field Transformation

json
{
  "op": "db.update",
  "collection": "users",
  "filter": { "_key": "user_123" },
  "data": {
    "$full_name": "first_name + ' ' + last_name",
    "greeting": "Hello {{ first_name }}!",
    "age_next_year": "?{{ age + 1 }}"
  }
}

Calculated Fields

json
{
  "op": "db.insert",
  "collection": "orders",
  "data": {
    "items": [
      { "product": "Widget", "price": 10, "quantity": 5 }
    ],
    "$subtotal": "@sum(@map(items, 'price * quantity'))",
    "tax": "?{{ subtotal * 0.08 }}",
    "total": "?{{ subtotal + (subtotal * 0.08) }}"
  }
}

Dynamic Status

json
{
  "op": "db.update",
  "collection": "subscriptions",
  "filter": { "_key": "sub_123" },
  "data": {
    "status": "{{ days_remaining > 0 ? 'active' : 'expired' }}",
    "renewal_message": "Renews in {{ days_remaining }} days",
    "$is_renewable": "days_remaining <= 7 && days_remaining > 0"
  }
}

Usage in Output Expressions

Template expressions in output expression for db.find results:

Format Query Results

json
{
  "op": "db.find",
  "collection": "users",
  "output": {
    "display_name": "{{ first_name }} {{ last_name }}",
    "contact": "{{ email }} | {{ phone }}",
    "$is_adult": "age >= 18"
  }
}

Calculate Derived Values

json
{
  "op": "db.find",
  "collection": "products",
  "output": {
    "name": "$name",
    "price_with_tax": "?{{ price * 1.08 }}",
    "discount_price": "?{{ price * 0.9 }}",
    "$savings": "price - (price * 0.9)"
  }
}

Conditional Formatting

json
{
  "op": "db.find",
  "collection": "orders",
  "output": {
    "order_id": "$order_id",
    "status_display": "{{ status == 'completed' ? '✓ Completed' : '⏳ Pending' }}",
    "total_formatted": "${{ total }} USD",
    "$needs_attention": "status == 'pending' && days_since_order > 7"
  }
}

Combining with Data Operators

Template expressions work alongside Data Operators:

json
{
  "op": "db.update",
  "collection": "users",
  "filter": { "_key": "user_123" },
  "data": {
    "name": "Jane Doe",
    "score:$incr": 10,
    "level": "?{{ score > 100 ? 2 : 1 }}",
    "$display_level": "'Level ' + level",
    "updated_at:$now": true,
    "summary": "{{ name }} - Level {{ level }} - {{ score }} points"
  }
}

Type Coercion

String Output ({{ }})

json
{
  "text_number": "{{ 42 }}",           // "42"
  "text_calc": "{{ 10 + 5 }}",         // "15"
  "text_bool": "{{ true }}",           // "true"
  "combined": "Value: {{ count }}"     // "Value: 10"
}

Native Type (?{{ }})

json
{
  "number": "?{{ 42 }}",               // 42
  "calculated": "?{{ 10 + 5 }}",       // 15
  "boolean": "?{{ true }}",            // true
  "result": "?{{ 5 > 3 }}"            // true
}

Common Patterns

User Profile Formatting

json
{
  "op": "db.find",
  "collection": "users",
  "output": {
    "$full_name": "first_name + ' ' + last_name",
    "bio": "{{ full_name }} from {{ city }}, {{ country }}",
    "$member_since": "@formatdate(created_at, 'YYYY')",
    "profile_complete": "?{{ @len(bio) > 0 && photo_url != null }}"
  }
}

Order Calculations

json
{
  "op": "db.insert",
  "collection": "orders",
  "data": {
    "items": [
      { "name": "Widget", "price": 29.99, "qty": 2 },
      { "name": "Gadget", "price": 49.99, "qty": 1 }
    ],
    "$subtotal": "@sum(@map(items, 'price * qty'))",
    "tax": "?{{ subtotal * 0.08 }}",
    "shipping": "?{{ subtotal >= 100 ? 0 : 9.99 }}",
    "total": "?{{ subtotal + (subtotal * 0.08) + (subtotal >= 100 ? 0 : 9.99) }}",
    "summary": "{{ @len(items) }} items - ${{ total }} total"
  }
}

Status Messages

json
{
  "op": "db.update",
  "collection": "tasks",
  "filter": { "_key": "task_123" },
  "data": {
    "status": "{{ completed ? 'done' : due_date < @now() ? 'overdue' : 'pending' }}",
    "status_emoji": "{{ completed ? '✓' : '⏳' }}",
    "message": "{{ status_emoji }} {{ title }} - {{ status }}"
  }
}

Conditional Badges

json
{
  "op": "db.find",
  "collection": "users",
  "output": {
    "name": "$name",
    "badge": "{{ points > 1000 ? 'gold' : points > 500 ? 'silver' : 'bronze' }}",
    "badge_emoji": "{{ badge == 'gold' ? '🏆' : badge == 'silver' ? '🥈' : '🥉' }}",
    "$display": "name + ' ' + badge_emoji"
  }
}

Syntax Reference

SyntaxTypeReturnsUse Case
{{ expr }}String templateStringText formatting, interpolation
?{{ expr }}Native evaluationNative typeNumbers, booleans, calculations
$fieldShorthandStringSimple expressions
fieldDirect referenceValueAccess document fields
@function()HelperVariesBuilt-in functions

Best Practices

Use Appropriate Syntax

For strings and text:

json
{
  "message": "Hello {{ name }}!",
  "label": "{{ category }}: {{ title }}"
}

For numbers and calculations:

json
{
  "total": "?{{ price * quantity }}",
  "percentage": "?{{ (value / total) * 100 }}"
}

For booleans:

json
{
  "is_eligible": "?{{ age >= 18 && verified }}",
  "can_purchase": "?{{ balance >= price }}"
}

Keep Expressions Simple

Good - clear and readable:

json
{
  "full_name": "{{ first_name }} {{ last_name }}",
  "total": "?{{ price + tax }}"
}

Avoid - too complex:

json
{
  "result": "?{{ ((a + b) * c) / d - (e * f) + (g > h ? i : j) }}"
}

For complex logic, break into multiple fields or use helper functions.

Consistent Field References

Use consistent naming:

json
{
  "$full_name": "first_name + ' ' + last_name",
  "$display_email": "email",
  "$formatted_phone": "@format(phone, 'XXX-XXX-XXXX')"
}

Notes

  • Template expressions have access to all document fields
  • Expressions are evaluated server-side during operation execution
  • Invalid expressions will result in operation errors
  • Use ?{{ }} for type-safe numeric and boolean operations
  • Helper functions are covered in detail in Helper Functions