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.insertoperations - 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
| Syntax | Type | Returns | Use Case |
|---|---|---|---|
{{ expr }} | String template | String | Text formatting, interpolation |
?{{ expr }} | Native evaluation | Native type | Numbers, booleans, calculations |
$field | Shorthand | String | Simple expressions |
field | Direct reference | Value | Access document fields |
@function() | Helper | Varies | Built-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