You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Operators are a set of symbols that implement commonly used functions and are easier to read that an equivalent notation that just used function syntax. Most operators act on two values, placed on the left-hand side (LHS) and right-hand side (RHS) of the operator. Expressions containing operators can be ready chained, the order in which they are evaluated is determined by their relative precedence.
8
7
9
-
## `.` (Map)
8
+
## `&` (Concatenation)
10
9
11
-
The dot operator is one of the fundamental building blocks in JSONata expressions. It implements the 'for each' or 'map' function that is common in many functional languages.
10
+
The string concatenation operator is used to join the string values of the operands into a single resultant string. If either or both of the operands are not strings, then they are first cast to string using the rules of the `$string` function.
12
11
13
-
The dot operator performs the following logic:
12
+
__Example__
14
13
15
-
- The expression on the LHS is evaluated to produce an array of values.
16
-
- If it evaluates to a single value, that is treated as equivalent to an array containing that single value
17
-
- If it evaluates to nothing (no match or empty array), then the result of the operator expression is nothing
18
-
- For each value in the LHS array in turn:
19
-
- The value is known as the _context_ and is used as the basis for any relative path expression on the RHS. It is also accessible in the RHS expression using the `$` symbol.
20
-
- The RHS expression is evaluated to produce a value or array of values (or nothing). These values are appended to a combined array of results for the operator as a whole.
21
-
- The combined result of the operator is returned.
14
+
`"Hello" & "World"` => `"HelloWorld"`
22
15
23
-
This operator is left associative meaning that the expression `a.b.c.d` is evaluated like `((a.b).c).d`; i.e. left to right
16
+
## `? :` (Conditional)
24
17
25
-
__Examples__
18
+
The conditional ternary operator is used to evaluate one of two alternative expressions based on the result of a predicate (test) condition. The operator takes the form:
The `<test_expr>` expression is first evaluated. If it evaluates to Boolean `true`, then the operator returns the result of evaluating the `<expr_T>` expression. Otherwise it returns the result of evaluating the `<expr_F>` expression. If `<test_expr>` evaluates to a non-Boolean value, then the value is first cast to Boolean using the rules of the `$boolean` function.
23
+
24
+
__Example__
25
+
26
+
`Price < 50 ? "Cheap" : "Expensive"`
27
+
28
+
## `:=` (Variable binding)
29
+
30
+
The variable binding operator is used to bind the value of the RHS to the variable name defined on the LHS. The variable binding is scoped to the current block and any nested blocks. It is an error if the LHS is not a `$` followed by a valid variable name.
31
+
32
+
__Examples__
33
+
34
+
-`$five := 5`
35
+
-`$square := function($n) { $n * $n }`
33
36
34
37
## `~>` (Chain)
35
38
@@ -66,34 +69,6 @@ For example, the expression
66
69
67
70
creates a new function `$uppertrim` that performs `$trim` followed by `$uppercase`.
68
71
69
-
## `^(`...`)` (Order-by)
70
-
71
-
The order-by operator is used to sort an array of values into ascending or descending order according to one or more expressions defined within the parentheses.
72
-
73
-
By default, the array will be sorted into ascending order. For example:
74
-
75
-
`Account.Order.Product^(Price)`
76
-
77
-
sorts all of the products into order of increasing price (`Price` is a numeric field in the `Product` object).
78
-
79
-
To sort in descending order, the sort expression must be preceded by the `>` symbol. For example:
80
-
81
-
`Account.Order.Product^(>Price)`
82
-
83
-
sorts all of the products into order of decreasing price. The `<` symbol can be used explicity indicate ascending order, although that is the default behaviour.
84
-
85
-
Secondary (and more) sort expressions can be specified by separating them with commas (`,`). The secondary expression will be used to determine order if the primary expression ranks two values the same. For example,
86
-
87
-
`Account.Order.Product^(>Price, <Quantity)`
88
-
89
-
orders the products primarily by decreasing price, but for products of the same price, by increasing quantity.
90
-
91
-
The sort expression(s) can be any valid JSONata expression that evaluates to a number or a string. If it evaluates to a string then the array is sorted in order of unicode codepoint.
92
-
93
-
__Examples__
94
-
95
-
-`Account.Order.Product^(Price * Quantity)` => Increasing order of price times quantity.
96
-
-`student[type='fulltime']^(DoB).name` => The names of all full time students sorted by date of birth (the DoB value is an ISO 8601 date format)
97
72
98
73
## `... ~> | ... | ... |` (Transform)
99
74
@@ -114,60 +89,32 @@ The `~>` operator is the operator for function chaining and passes the value on
defines a transform that will return a deep copy the object passed to it, but with the `Product` object modified such that its `Price` property has had its value increased by 20%. The first part of the expression is the path location that specifies all of the objects within the overall object to change, and the second part defines an object that will get merged into the object(s) matched by the first part. The merging semantics is the same as that of the `$merge()` function.
120
95
121
96
This transform definition syntax creates a JSONata function which you can either assign to a variable and use multiple times, or invoke inline.
This copies the input, but for each `Product` it inserts a Total and removes the `Price` and `Quantity` properties.
145
120
146
-
## `&` (Concatenation)
147
-
148
-
The string concatenation operator is used to join the string values of the operands into a single resultant string. If either or both of the operands are not strings, then they are first cast to string using the rules of the `$string` function.
149
-
150
-
__Example__
151
-
152
-
`"Hello" & "World"` => `"HelloWorld"`
153
-
154
-
## `? :` (Conditional)
155
-
156
-
The conditional ternary operator is used to evaluate one of two alternative expressions based on the result of a predicate (test) condition. The operator takes the form:
157
-
158
-
`<test_expr> ? <expr_T> : <expr_F>`
159
-
160
-
The `<test_expr>` expression is first evaluated. If it evaluates to Boolean `true`, then the operator returns the result of evaluating the `<expr_T>` expression. Otherwise it returns the result of evaluating the `<expr_F>` expression. If `<test_expr>` evaluates to a non-Boolean value, then the value is first cast to Boolean using the rules of the `$boolean` function.
161
-
162
-
__Example__
163
-
164
-
`Price < 50 ? "Cheap" : "Expensive"`
165
-
166
-
## `:=` (Variable binding)
167
-
168
-
The variable binding operator is used to bind the value of the RHS to the variable name defined on the LHS. The variable binding is scoped to the current block and any nested blocks. It is an error if the LHS is not a `$` followed by a valid variable name.
The path operators underpin the declarative nature of the map/filter/reduce processing model in JSONata.
8
+
9
+
## `.` (Map)
10
+
11
+
The dot operator is one of the fundamental building blocks in JSONata expressions. It implements the 'for each' or 'map' function that is common in many functional languages.
12
+
13
+
The dot operator performs the following logic:
14
+
15
+
- The expression on the LHS is evaluated to produce an array of values.
16
+
- If it evaluates to a single value, that is treated as equivalent to an array containing that single value
17
+
- If it evaluates to nothing (no match or empty array), then the result of the operator expression is nothing
18
+
- For each value in the LHS array in turn:
19
+
- The value is known as the _context_ and is used as the basis for any relative path expression on the RHS. It is also accessible in the RHS expression using the `$` symbol.
20
+
- The RHS expression is evaluated to produce a value or array of values (or nothing). These values are appended to a combined array of results for the operator as a whole.
21
+
- The combined result of the operator is returned.
22
+
23
+
This operator is left associative meaning that the expression `a.b.c.d` is evaluated like `((a.b).c).d`; i.e. left to right
The filter operator (a.k.a predicate) is used to select only the items in the input sequence that satisfy the predicate expression contained between the square brackets.
35
+
36
+
If the predicate expression is an integer, or an expression that evaluates to an integer, then the item at that position (zero offset) in the input sequence is the only item selected for the result sequence.
37
+
If the number is non-integer, then it is rounded _down_ to the nearest integer.
38
+
39
+
If the predicate expression is an array of integers, or an expression that evaluates to an array of integers, then the items at those positions (zero offset) in the input sequence is the only item selected for the result sequence.
40
+
41
+
If the predicate expression evaluates to any other value, then it is cast to a Boolean as if using the `$boolean()` function. If this evaluates to `true`, then the item is retained in the result sequence. Otherwise it is rejected.
42
+
43
+
See [Navigating JSON Arrays](simple#navigating-json-arrays) and [Predicates](predicate) for more details and examples.
44
+
45
+
## `^(` ... `)` (Order-by)
46
+
47
+
The order-by operator is used to sort an array of values into ascending or descending order according to one or more expressions defined within the parentheses.
48
+
49
+
By default, the array will be sorted into ascending order. For example:
50
+
51
+
`Account.Order.Product^(Price)`
52
+
53
+
sorts all of the products into order of increasing price (`Price` is a numeric field in the `Product` object).
54
+
55
+
To sort in descending order, the sort expression must be preceded by the `>` symbol. For example:
56
+
57
+
`Account.Order.Product^(>Price)`
58
+
59
+
sorts all of the products into order of decreasing price. The `<` symbol can be used explicitly indicate ascending order, although that is the default behaviour.
60
+
61
+
Secondary (and more) sort expressions can be specified by separating them with commas (`,`). The secondary expression will be used to determine order if the primary expression ranks two values the same. For example,
62
+
63
+
`Account.Order.Product^(>Price, <Quantity)`
64
+
65
+
orders the products primarily by decreasing price, but for products of the same price, by increasing quantity.
66
+
67
+
The sort expression(s) can be any valid JSONata expression that evaluates to a number or a string. If it evaluates to a string then the array is sorted in order of unicode codepoint.
68
+
69
+
__Examples__
70
+
71
+
-`Account.Order.Product^(Price * Quantity)` => Increasing order of price times quantity.
72
+
-`student[type='fulltime']^(DoB).name` => The names of all full time students sorted by date of birth (the DoB value is an ISO 8601 date format)
73
+
74
+
## `{` ... `}` (Reduce)
75
+
76
+
The reduce operator can be used as the last step in a path expression to group and aggregate its input sequence into a single object.
77
+
The key/value pairs between the curly braces determine the groupings (by evaluating the key expression) and the aggregated values for each group.
78
+
See [Grouping and Aggregation](sorting-grouping#grouping) for more details.
79
+
80
+
81
+
## `#` (Positional variable binding)
82
+
83
+
This can be used to determine at which position in the sequence the current context item is. It can be used following any map, filter or order-by stage in the path.
84
+
The variable is available for use within subsequent stages of the path (e.g. within filter predicates) and goes out of scope at the end of the path expression.
85
+
86
+
__Example__
87
+
88
+
```
89
+
library.books#$i['Kernighan' in authors].{
90
+
'title': title,
91
+
'index': $i
92
+
}
93
+
```
94
+
This returns an array of objects for each book in the library where Kernighan is one of the authors. Each object contains the book's title and its position within the books array before it was filtered.
95
+
96
+
97
+
## `@` (Context variable binding)
98
+
99
+
This is used to bind the current context item (`$`) to a named variable. It can only be used directly following a map stage, not a filter or order-by stage.
100
+
The variable binding remains in scope for the remainder of the path expression.
101
+
102
+
Because the current context has now been explicitly bound to a named variable, this context will be carried forward to be the context of the next stage in the path.
103
+
For example, in this snippet of a path, `library.loans@$l.books`, the loans array is a property of the library object and each loan will, in turn, be bound to the variable `$l`.
104
+
The books array, which is also a property of the library object, will then be selected.
105
+
106
+
This operator can be used to perform data joins within a path because of its ability to do cross-referencing across objects.
107
+
108
+
__Example__
109
+
110
+
```
111
+
library.loans@$l.books@$b[$l.isbn=$b.isbn].{
112
+
'title': $b.title,
113
+
'customer': $l.customer
114
+
}
115
+
```
116
+
This performs an 'inner join' between objects in the loans array and objects in the books array where the ISBNs match between the structures.
117
+
118
+
Block expressions can be used to widen the scope of the data cross-referencing as shown in this example:
Copy file name to clipboardExpand all lines: docs/processing.md
+22-18Lines changed: 22 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,30 +32,34 @@ The sequence flattening rules are as follows:
32
32
33
33
4. If a sequence contains one or more (sub-)sequences, then the values from the sub-sequence are pulled up to the level of the outer sequence. A result sequence will never contain child sequences (they are flattened).
34
34
35
-
__Examples__
36
35
37
-
TODO
38
36
39
-
## The path processing pipeline
37
+
## JSONata path processing
40
38
41
-
TODO (from tech talk ppt)
39
+
The JSONata path expression is a _declarative functional_ language.
42
40
43
-
## The map/filter/reduce programming paradigm
41
+
__Functional__ because it is based on the map/filter/reduce programming paradigm as supported by popular functional programming languages through the use of higher-order functions.
44
42
45
-
With references to literature
43
+
__Declarative__ because these higher-order functions are exposed through a lightweight syntax which lets the user focus on the intention of the query (declaration) rather than the programming constructs that control their evaluation.
46
44
47
-
## Generating sequences
45
+
A path expression is a sequence of one or more of the following functional stages:
48
46
49
-
From location paths
47
+
Stage | Syntax | Action
48
+
---|---|---
49
+
__Map__ | seq`.`expr | Evaluates the RHS expression in the context of each item in the input sequence. Flattens results into result sequence.
50
+
__Filter__ | seq`[`expr`]` | Filter results from previous stage by applying predicate expression between brackets to each item.
51
+
__Sort__ | seq`^(`expr`)` | Sorts (re-orders) the input sequence according to the criteria in parentheses.
52
+
__Index__ | seq`#`$var | Binds a named variable to the current context position (zero offset) in the sequence.
53
+
__Join__ | seq`@`$var | Binds a named variable to the current current context item in the sequence. Can only be used directly following a map stage.
54
+
__Reduce__ | seq`{` expr`:`expr`,` expr`:`expr ...`}` | Group and aggregate the input sequence to a single result object as defined by the name/value expressions. Can only appear as the final stage in a path expression.
50
55
51
-
From literal array constructor
56
+
In the above table:
52
57
53
-
With the range operator
54
-
55
-
## Generic ‘map’ operator
56
-
57
-
## The ‘filter’ stage
58
-
59
-
## Aggregating (reduce)
60
-
61
-
## JSONata syntax built on this model
58
+
- In the 'Syntax' column, 'seq' refers to the input sequence for the current stage, which is the result sequence from the previous stage.
59
+
- The 'Action' column gives a brief outline of the stage's behavior; fuller details are in the [Path Operators](path-operators) reference page.
60
+
- The relative precedence of each operator affects the scope of its influence on the input sequence. Specifically,
61
+
- The Filter operator binds tighter than the Map operator. This means, for example, that `books.authors[0]` will select the all of the first authors from _each_ book rather than the first author from all of the books.
62
+
- The Sort (order-by) operator has the lowest precedence, meaning that the full path to the left of it will be evaluated, and its result sequence will be sorted.
63
+
- This operator precedence can be overridden by using parentheses. For example, `(books.authors)[0]` will select the the first author from all of the books (single value). Note, however, that parentheses also define a scope frame for variables, so any variables that have been bound within the parentheses block including those bound by the `@` and `#` operators will go out of scope at the end of the parens block.
64
+
- The variables bound by the `@` and `#` operators go out of scope at the end of the path expression.
65
+
- The Reduce stage, if used, will terminate the current path expression. Although a Map operator can immediately follow this, it will be interpreted as the start of a new path expression, meaning that any previously bound context or index variables will be out of scope.
0 commit comments