# DataWeave Operators

DataWeave version 2 supports several operators, including mathematical operators, equality operators, and operators such as prepend, append and update. Before you begin, note that DataWeave version 2 is for Mule 4 apps. For Mule 3 apps, refer to DataWeave Operators in the Mule 3.9 documentation. For other Mule versions, you can use the version selector for the Mule Runtime table of contents.

## Mathematical Operators

DataWeave version 2 supports the most common mathematical operators:

Operator Description

`+`

`-`

For subtraction.

`*`

For multiplication.

`/`

For division.

In addition to operating with numbers, the `(-)` and `(+)` operators can also operate with complex data structures like arrays, objects, and dates.

The following example uses mathematical operators with different data types:

Source
``````%dw 2.0
output application/json
---
{ "mathOperators" : [
{ "2 + 2" : (2 + 2) },
{ "2 - 2" : (2 - 2) },
{ "2 * 2" : (2 * 2) },
{ "2 / 2" : (2 / 2) },
{ "[1,2,3] - 1 + 4" : [1,2,3] - 1 + 4},
{ "{a:1, b:2, c:3} - 'a' " : {a:1, b:2, c:3} - "a"},
{ "|2021-03-02T10:39:59| - |P1D| + |PT3H|" : |2021-03-02T10:39:59| - |P1D| + |PT3H|}
]
}``````
Output
``````{
"mathOperators": [
{ "2 + 2": 4 },
{ "2 - 2": 0 },
{ "2 * 2": 4 },
{ "2 / 2": 1 },
{ "[1,2,3] - 1 + 4": [2,3,4] },
{ "{a:1, b:2, c:3} - 'a' ": {"b": 2, "c": 3} },
{ "|2021-03-02T10:39:59| - |P1D| + |PT3H|": "2021-03-01T13:39:59" }]
}``````

Several DataWeave functions operate on numbers, for example: sum, mod (for modulo), and avg (for average).

## Equality and Relational Operators

DataWeave version 2 supports the following equality and relational operators:

Operator Description

`<`

For less than.

`>`

For greater than.

`<=`

For less than or equal to.

`>=`

For greater than or equal to.

`==`

For equal to.

`~=`

Equality operator that tries to coerce one value to the type of the other when the types are different.

Note that you can negate these operators by using the logical operator, `not`.

The following example uses relational operators:

Source
``````%dw 2.0
output application/json
---
{ "relational" : [
{ "1 < 1" : (1 < 1) },
{ "1 > 2" : (1 > 2) },
{ "1 <= 1" : (1 <= 1) },
{ "1 >= 1" : (1 >= 1) }
]
}``````
Output
``````{ "relational": [
{ "(1 < 1)": false },
{ "(1 > 2)": false },
{ "(1 <= 1)": true },
{ "(1 >= 1)": true }
]
}``````

Note that if the operands of the relational operator belong to different types, DataWeave coerces the right-side operand to the type of the left-side operand. For example, in the expression `"123" > 12` DataWeave coerces `12` (a Number type) to `"12"` (a String type) and compares each String value lexicographically. In the expression `123 > "12"`, DataWeave coerces the String value `"12"` to the Number value `12` and compares the numbers.

These examples use equality operators:

Source
``````%dw 2.0
output application/dw
---
{ "equality" :
[
(1 == 1),
(1 == 2),
("true" == true),
("true" ~= true),
(['true'] ~= [true]),
('1' ~= 1)
]
}``````
Output
``````{
equality: [ true, false, false, true, true, true ]
}``````

## Logical Operators

DataWeave version 2 supports the following logical operators:

Operator Description

`not`

Negates the result of the input. See also, `!`.

`!`

Negates the result of the input. See also, `not`. Introduced in DataWeave 2.2.0. Supported by Mule 4.2 and later.

`and`

Returns `true` if the result of all inputs is true, `false` if not.

`or`

Returns `true` if the result of any input is true, `false` if not.

 Though the semantics of `not` and `!` are the same, their precedence differs. `not true or true` is executed as `not (true or true)`, so it returns `false`, whereas `!true or true` returns `true` because the `!` only applies to the first `true`. `!(true or true)` returns `false`.

The following examples use logical operators:

Source
``````%dw 2.0
var myArray = [1,2,3,4,5]
var myMap = myArray map not ((\$ mod 2) == 0)
output application/json
---
{
"not" : [
"notTrue" : not true,
"notFalse" : not false,
"myMapWithNot" : myMap
],
"and" : [
"andTrueFalse" : true and false,
"andIsTrue" : (1 + 1 == 2) and (2 + 2 == 4),
"andIsFalse" : (1 + 1 == 2) and (2 + 2 == 2)
],
"or" : [
"orTrueFalse" : true or false,
"orIsTrue" : (1 + 1 == 2) or (2 + 2 == 2),
"orIsFalse" : (1 + 1 == 1) or (2 + 2 == 2)
],
"!-vs-not" : [
"example-!" : (! true or true),
"example-not" : (not true or true)
]
}``````

Note that `myMap` iterates through the items in a list (`myArray`) and determines whether the modulo (`mod`) expression does not evaluate to `0` when applied to each given item.

Output
``````{
"not": [
{ "notTrue": false },
{ "notFalse": true },
{ "myMapWithNot": [ true, false, true, false, true ] }
],
"and": [
{ "andTrueFalse": false },
{ "andIsTrue": true },
{ "andIsFalse": false }
],
"or": [
{ "orTrueFalse": true },
{ "orIsTrue": true },
{ "orIsFalse": false }
],
"!-vs-not": [
{ "example-!": true },
{ "example-not": false }
]
}``````

Note that `not` works in expressions such as `not (true)`, but `not(true)` (without the space) does not work.

You can use logical operators together. The following example uses:

• `or not` as defined in the `orNot` expression.

• `and not` in `andNot`.

• `not` and `and not` in `notWithAndNot`.

``````%dw 2.0
var orNot = if (1 + 1 == 4 or not 1 == 2) {"answer": "orNot - Condition met"}
var andNot = if (1 + 1 == 2 and not 1 == 2) {"answer": "andNot - Condition met"}
var notWithAndNot = if (not (1 + 1 == 2 and not 1 == 1)) {"answer": "notWithAndNot - Condition met"}
output application/json
---
[
orNot,
andNot,
notWithAndNot
]
}``````
Output
``````{
{ "answer": "orNot - Condition met" },
{ "answer": "andNot - Condition met" },
{ "answer": "notWithAndNot - Condition met" }
]
}``````

DataWeave executes the code inside each `if` block because all conditional expressions in the example evaluate to `true`.

## Prepend, Append, and Remove Operators for Arrays

DataWeave version 2 supports operators for appending and prepending items within an array:

Operator Description

`>>`

Prepends data on the left-hand side of the operator to items in the array on the right-hand side. For example, `1 >> ` results in `[ 1, 2 ]`, prepending `1` to `2` in the array.

`<<`

Appends data on the right-hand side of the operator to items in the array on the left-hand side. For example, ` << 2` results in `[ 1, 2 ]`, appending `2` to `1` in the array.

`+`

Appends data on the right-hand side of the operator to items in the array on the left-hand side. For example, ` + 2` results in `[ 1, 2 ]`, appending `2` to `1` in the array. The array is always on the left-hand side of the operator.

`-`

Removes a specified element of any supported type from an array.

The following examples show uses of prepend, append, and remove operators on arrays:

``````%dw 2.0
output application/json
---
{
"prepend-append" : [
// Array on right side when prepending.
{ "prepend" : 1 >>  },
{ "prepend-number" : 1 >>  },
{ "prepend-string" : "a" >>  },
{ "prepend-object" : { "a" : "b"} >>  },
{ "prepend-array" :  >> [2, 3] },
{ "prepend-binary" : (1 as Binary) >>  },
{ "prepend-date-time" : |23:57:59Z| >> [ |2017-10-01| ] },
// Array is on left side when appending.
{ "append-number" :  << 2 },
{ "append-string" :  << "a" },
{ "append-object" :  << { "a" : "b"} },
{ "append-array" : [1,2] << [1, 2, 3] },
{ "append-binary" :  << (1 as Binary) },
{ "append-date-time" : [ |2017-10-01| ] << |23:57:59Z| },
{ "append-object-to-array" : [1,2] << {"a" : "b"} },
{ "append-array-to-array1" : ["a","b"] << ["c","d"] },
{ "append-array-to-array2" : [["a","b"],["c","d"]] << ["e","f"] },
// + always appends within the array
{ "append-with-+" :  + 2 },
{ "append-with-+" :  + 1 },
{ "removeNumberFromArray" : ( [1,2,3] - 2 ) },
{ "removeObjectFromArray" : ( [ {a : "b"}, {c : "d"} , { e : "f"} ] - { c : "d"} ) }
]
}``````
Output
``````{
"prepend-append": [
{ "prepend": [ 1, 2 ] },
{ "prepend-number": [ 1, 1 ] },
{ "prepend-string": [ "a", 1 ] },
{ "prepend-array": [ [ 1 ], 2, 3 ] },
{ "prepend-object": [ { "a": "b" }, 1 ] },
{ "prepend-binary": [ "\u0001", 1 ] },
{ "prepend-date-time": [ "23:57:59Z", "2017-10-01" ] },
{ "append-number": [ 1, 2 ] },
{ "append-string": [ 1, "a" ] },
{ "append-object": [ 1, { "a": "b" } ] },
{ "append-array": [ 1, 2, [ 1, 2, 3 ] ] },
{ "append-binary": [ 1, "\u0001" ] },
{ "append-date-time": [ "2017-10-01", "23:57:59Z" ] },
{ "append-object-to-array": [ 1, 2, { "a": "b" } ] },
{ "append-array-to-array1": [ "a", "b", ["c","d"] ] },
{ "append-array-to-array2": [ ["a","b"], ["c","d"], ["e","f"] ] },
{ "append-with-+": [ 1, 2] },
{ "append-with-+": [ 2, 1] },
{ "removeNumberFromArray": [ 1, 3 ] },
{ "removeObjectFromArray": [ { "a": "b" }, { "e": "f" } ] }
]
}``````

## Scope and Flow Control Operators

DataWeave version 2 supports operators that control the flow and scope of expressions:

Table 1. Scope Operators:
Operator Description

`do`

Creates a scope in which new variables, functions, annotations, or namespaces can be declared and used. The syntax is similar to a mapping in that it is composed of a header and body separated by `---`. Its header is where all the declarations are defined, and its body is the result of the expression. See do and Examples: Local DataWeave Variables for examples.

`using`

Replaced by `do`. Supported for backwards compatibility only.

Table 2. Flow Control Operators:
Operator Description

`if else`

An `if` operator evaluates a conditional expression and returns the value under the `if` only if the conditional expression is true. Otherwise, it returns the expression under `else`. Every `if` expression must have a matching `else` expression. See if else for an example.

`else if`

An `else` operator chains expressions together within an if-else construct by incorporating `else if`. See else if for an example.

## Update Operator

DataWeave supports the `update` operator, which enables you to update specified fields of a data structure with new values.

Introduced in DataWeave 2.3.0. Supported by Mule 4.3 and later.

Versions prior to Mule 4.3 require the following syntax to increase the `age` value in `myInput` by one without recreating the entire object:

``````%dw 2.0
var myInput = {
"name": "Ken",
"lastName":"Shokida",
"age": 30
}
output application/json
---
myInput mapObject ((value,key) ->
if(key as String == "age")
{(key): value as Number + 1}
else
{(key): value} )``````

In Mule 4.3, the `update` operator simplifies the syntax:

``````%dw 2.0
var myInput = {
"name": "Ken",
"lastName":"Shokida",
"age": 30
}
output application/json
---
myInput update {
case age at .age -> age + 1
}``````

Both DataWeave scripts return the same result:

``````{
"name": "Ken",
"lastName": "Shokida",
"age": 31
}``````

With `update`, casting or iterating through all the key-value pairs is not necessary.

The `update` syntax is as follows:

``````<value_to_update> update {
case <variable_name> at <update_expression>[!]? [if(<conditional_expression>)]? -> <new value>
...
}``````
• `value_to_update` represents the original value to update.

• `update_expression` is the selector expression that matches a value in `value_to_update`.

• `variable_name` is the name of the variable to bind to the matched `update_expression` value.

• `new_value` is the expression with the new value.

• `[if(<conditional_expression>)]?` If `conditional_expression` returns `true`, the script updates the value. Use of a conditional expression is optional.

• `[!]` marks the selector as an upsert. If the expression doesn’t find a match, the `!` makes the `update` operator create all the required elements and insert the new value.

• `update_expression` supports multiple `case` expressions.

 The `update` operator doesn’t mutate the existing value. Instead, the operator creates a new value with the updated expressions.

### Selector Expressions

Use selector expressions with the `update` operator to specify the fields to update.

#### Value Selector

This matching selector can check for matches to any value within an object.

The following example updates a field at the root level and a field in a nested level using the value selector:

Source
``````%dw 2.0
var myInput = {
"name": "Ken",
"lastName":"Shokida",
"age": 30,
"street": "Amenabar",
"zipCode": "AB1234"
}
}
output application/json
---
myInput update {
case age at .age -> age + 1
case s at .address.street -> "First Street"
}``````
Output
``````{
"name": "Ken",
"lastName": "Shokida",
"age": 31,
"street": "First Street",
"zipCode": "AB1234"
}
}``````

#### Index Selector

This matching selector enables you to match any array by its index.

The following example updates an element that is at the first location of the array:

Input
``````{
"name": "Ken",
"lastName":"Shokida",
"age": 30,
"street": "Amenabar",
"zipCode": "AB1234"
}]
}``````
Source
``````%dw 2.0
output application/json
---
case s at .addresses -> {
"street": "Second Street",
"zipCode": "ZZ123"
}
}``````
Output
``````{
"name": "Ken",
"lastName": "Shokida",
"age": 30,
{
"street": "Second Street",
"zipCode": "ZZ123"
}
]
}``````

#### Attribute Selector

This matching selector enables you to match any attribute value.

The following example updates an attribute value and changes it to upper case:

Input
``<user name="leandro"/>``
Source
``````%dw 2.0
output application/json
---
case name at .user.@name -> upper(name)
}``````
Output
``````<?xml version='1.0' encoding='UTF-8'?>
<user name="LEANDRO"/>``````

#### Dynamic Selector

Any selector can incorporate an expression to make the selection dynamic.

The following example dynamically selects and updates the value of a field that is not hardcoded. Such a field can change at runtime. The example uses the variable `theFieldName` to obtain the field with key `name`, and it changes the value of that field to `Shoki`.

Input
``````{
"name": "Ken",
"lastName":"Shokida"
}``````
Source
``````%dw 2.0
var theFieldName = "name"
output application/json
---
case s at ."\$(theFieldName)" -> "Shoki"
}``````
Output
``````{
"name": "Shoki",
"lastName": "Shokida"
}``````

### Conditional Update

The `update` operator has syntax for writing a conditional update if you want to modify a field under a given condition.

The following example updates the category based on the name of the user:

Input
``[{"name": "Ken", "age": 30}, {"name": "Tomo", "age": 70}, {"name": "Kajika", "age": 10}]``
Source
``````%dw 2.0
output application/json
---
user update {
case name at .name if(name == "Ken") -> name ++ " (Leandro)"
case name at .name if(name == "Tomo") -> name ++ " (Christian)"
}
)``````
Output
``````[
{
"name": "Ken (Leandro)",
"age": 30
},
{
"name": "Tomo (Christian)",
"age": 70
},
{
"name": "Kajika",
"age": 10
}
]``````

### Upserting

The `update` operator enables you to insert a field that is not present already by using the `!` symbol at the end of the selector expression. When the field is not present, the operator binds a `null` value to the variable.

The following example updates each object in the array `myInput`. If the field `name` is present in the object, the example applies the `upper` function to the value of `name`. If the field `name` is not present in the object, the example appends the key-value pair `"name": "JOHN"` to the object.

Source
``````%dw 2.0
var myInput = [{"lastName": "Doe"}, {"lastName": "Parker", "name": "Peter" }]
output application/json
---
myInput  map ((value) ->
value update {
case name at .name! -> if(name == null) "JOHN" else upper(name)
}
)``````
Output
``````[
{
"lastName": "Doe",
"name": "JOHN"
},
{
"lastName": "Parker",
"name": "PETER"
}
]``````

### Sugar Syntax

The `update` operator accepts a default variable named `\$` in place of the longer `<variable_name> at` syntax.

The following example binds the value of the expression `.age` to the default variable name `\$`, which is used to express the new value. The longer equivalent is shown in comments.

Input
``````{
"name": "Ken",
"lastName":"Shokida",
"age": 30,
"street": "Amenabar",
"zipCode": "AB1234"
}
}``````
Source
``````%dw 2.0
output application/json
---
//equivalent expression:
//case age at .age -> age + 1
case .age -> \$ + 1
``````{