Understanding JOLT operators (wildcards)

Learn how wildcards help you build dynamic, concise, and adaptable JOLT transformation rules.

JOLT operators, also known as wildcards, are one of the most powerful features of the framework. They allow you to manipulate values, capture field names, handle optional inputs, and build flexible structures even when the input format varies.

In this guide, you’ll see how each operator works, what kinds of problems it solves, and how to use it to simplify both basic and advanced transformation scenarios.

Important concepts

Until now, we’ve covered the essential concepts of JOLT. Before moving forward with the advanced operations, we need to introduce two key elements used throughout all JOLT specifications: LHS and RHS.

LHS and RHS

Every JOLT operation is built around two sides:

  • LHS (Left Hand Side): The part before the colon (:), where we select or match fields from the input.

  • RHS (Right Hand Side): The part after the colon (:), where we assign or map values to the output.

Operators behave differently on the LHS and the RHS, and understanding this distinction is essential for building powerful, adaptable transformation rules.

Example:

[
 {
   "operation": "shift",
   "spec": {
LHS -> "customer": {
 LHS ->  "name": "client.fullName",  <- RHS
 LHS ->  "birhtDate": "client.dateOfBirth",  <- RHS
 LHS ->  "address": "client.address.street",  <- RHS
 LHS ->  "country": "client.address.country"  <- RHS
     }
   }
 }
}
]

Deep dive into operators

Let’s take a closer look at each operator and see how it behaves in real transformations. In the next sections, you’ll find explanations and examples that show exactly how each one works and what kind of output it produces.

& (ampersand)

Uses the field name found on the LHS to build the structure on the output JSON, without requiring you to explicitly define the name on the RHS.

  • Usage: RHS

  • Operation: shift

Practical example

  • Use case: Grouping related customer fields under a single parent object for better organization.

  • Goal: Move existing fields into a new client object without renaming them.

Input JSON

Desired output JSON

Transformation spec

Explanation

This transformation moves the original name and email fields into a new client object.

The & wildcard keeps the same field name from the input when creating the output structure.

  • "name": "client.&" takes the value of name and places it inside client.name.

  • "email": "client.&" does the same for email, generating client.email.

By using &, you don't need to manually repeat each field name on the RHS — JOLT automatically preserves it while nesting the fields under client.

* (asterisk)

References all fields or objects without needing to explicitly list each one.

  • Usage: LHS

  • Operations: shift, remove, cardinality, modify-default-beta, modify-overwrite-beta

Practical example

  • Use case: Organizing customer data by grouping all fields under a single parent object.

  • Goal: Nest all fields inside a customer object and rename document to ssn.

Input JSON

Desired output JSON

Transformation spec

Explanation

In the line "*": "customer.&", we take any field found in the input JSON and place it inside a new customer object, preserving both the field name and its entire structure.

For the document field, we take its value and map it to a new field called ssn, also inside the customer object.

How it works:

  • * matches any field.

  • & keeps the original field name and value.

  • When used together (* + &), JOLT automatically copies all matched fields without requiring you to specify them one by one.

This combination is useful when you need to manipulate or reorganize a JSON without knowing its full structure in advance.

@ (at sign)

References the value of a field.

Its behavior changes depending on the operation and whether it is used on the LHS or RHS.

  • Usage: LHS and RHS

  • Operations: shift, modify-default-beta, modify-overwrite-beta

shift example

  • Use case: Dynamically creating field names based on input values.

  • Goal: Use the value of key to define the field name inside product, assigning it the value from value.

Input JSON

Desired output JSON

Transformation spec

Explanation

In product.@(1,key), the expression @(1,key) tells JOLT to:

  • Go one level up (because of the 1),

  • Find the field called key,

  • Use its value ("code") as the name of the new field inside product.

This means the value of "value" ("123-ABC") is assigned to a dynamically named field ("code").

How @ works:

  • @ references data from another part of the JSON.

  • The first argument (1) indicates how many levels up to look.

  • The second argument (key) indicates which field’s value to retrieve.

  • The same logic applies when @ is used on the LHS or RHS of the spec.

This mechanism allows you to dynamically create field names based on values from the input JSON, enabling more flexible transformations.

modify-default-beta and modify-overwrite-beta examples

  • Use case: Enriching a nested object with information stored elsewhere in the JSON.

  • Goal: Add a company field inside product, using the value from the top-level manufacturer field.

Input JSON

Desired output JSON

Transformation spec

Explanation

We create a new field called company inside the product object and assign it the value of the manufacturer field.

To do this, we use @(2,manufacturer), which tells JOLT to:

  • Go two levels up (from inside product),

  • Find the field named manufacturer,

  • Retrieve its value and assign it to product.company.

modify-default-beta vs. modify-overwrite-beta

  • modify-default-beta: Adds the company field only if it doesn’t already exist inside product. It preserves existing values.

  • modify-overwrite-beta: Adds the company field even if it already exists, always replacing the existing value. As the name suggests, it overwrites any existing content.

Both operations use the same transformation spec. Only their behavior regarding overwriting differs.

$ (dollar sign)

References the name of a field instead of its value.

  • Usage: LHS

  • Operation: shift

Practical example

  • Use case: Identifying which fields a product object contains.

  • Goal: Generate a list with the names of all fields inside product.

Input JSON

Desired output JSON

Transformation spec

Explanation

We select all (*) fields inside the product object and use $ to retrieve each field’s name, not its value. Then, we place each retrieved name into the product[] list.

This allows us to generate a structure that captures only the field names from the input JSON.

# (hash)

The # operator has different functions depending on where it is used:

  • Usage:

    • LHS: Allows inserting manual (constant) values into the output JSON.

    • RHS: Used exclusively to create lists, grouping content from higher levels into a new list structure.

  • Operation: shift

LHS example

  • Use case: Adding a missing field that isn’t provided in the input JSON.

  • Goal: Insert a default category field inside product while preserving all existing fields.

Input JSON

Desired output JSON

Transformation spec

Explanation

The value after the # wildcard (DEFAULT-CATEGORY) is manually inserted into the field specified in the RHS (product.category).

This ensures the field is always included, regardless of the input.

RHS example

  • Use case: Standardizing field names inside an array of product objects.

  • Goal: Rename the value field to price for every item in the products array.

Input JSON

Desired output JSON

Transformation spec

Explanation

Using # in the RHS means:

  • We are creating a list ([...]).

  • #2 tells JOLT to group elements based on the structure found two levels above.

  • This guarantees that each code and its corresponding price stay together within the same product object.

So:

  • "code": "products[#2].&": Takes the code value and places it under the code field inside the new products list.

  • "value": "products[#2].price": Takes the value field and writes it as price inside the same list item.

By looking 2 levels up, JOLT preserves the original grouping of each product when forming the new list.

| (pipe)

The | operator allows referencing multiple possible field names in the input JSON and mapping all of them to the same destination in the output JSON.

This is useful when the input structure may vary, but the output needs to remain consistent.

  • Usage: LHS

  • Operation: shift

Practical example

  • Use case: Handling different naming conventions for the same customer field.

  • Goal: Map either fullName or customerName to a unified name field.

Input JSON

Desired output JSON

Transformation spec

Explanation

  • "fullName|customerName" means: If either fullName or customerName is present, its value will be assigned to customer.name.

  • "email": "customer.&" preserves the field name and maps the email value as is.

This ensures the output remains consistent even when the input uses different naming conventions.

Continue learning

Now that you understand how this operator works, here are a few next steps you can explore:

Last updated

Was this helpful?