13.12 JSON_TRANSFORM Operator NESTED PATH
JSON_TRANSFORM
operator NESTED PATH
defines a scope — a particular part of your data — within which to apply a sequence
of operations. The main use case for a nested-path operation is iterating over array
elements.
As a construct for downscoping, a nested-path operation limits modification to a subset of your data. It is not, itself, a modification operation.
The operations performed within the scope of a nested-path operation can include other nested-path operations. That is, you can use a nested path within a nested path,..., defining narrower scopes within wider ones, to act on data at any level. In particular, nested paths let you act on the elements of an array nested anywhere.
A nested scope is defined by a target path that immediately follows
operator NESTED PATH
(keyword PATH
can be
omitted). That path is then followed by the sequence of zero or more scoped
operations, within parentheses ((
,
)
).
The context item for the target path is specified in that path using
$
, if the NESTED PATH
operation with that target
is in the topmost (outermost) context. It is specified using @
otherwise, that is, if the NESTED PATH
operation with that target is
inside another
NESTED PATH
.
The data specified by the target path becomes the context item for the
scoped operations. In those operations, it is denoted @
,
instead of $
.
For example, '$.employees[*]'
can be used as the
target path in the topmost context; '@.employees[*]'
can be used
as the target path in a nested scope. The object with targeted field
employees
is at the top level in the first case; it is at some
lower level in the second case.
In either case, the target path defines each element in array
employees
as the context item for the scoped operations — each
operation is applied to one of those elements at a time, in array order.
Similarly, '$.employees[2 to 10]'
applies the scoped
operations to the third through eleventh employees, in turn; and
'$.employees[3,7]'
applies them to the fourth and then the seventh
employee. (Likewise, with @
in place of $
.)
In the following code, the targeted path is $.LineItems[*]
,
so occurrences of @
in the parenthesized sequence of operations are an
abbreviation for $.LineItems[*]
. This code changes the
UnitPrice
of each element in array LineItems
, by
multiplying it by 1.02
.
json_transform(data,
NESTED PATH '$.LineItems[*]'
(SET '@Part.UnitPrice' = PATH '@.UnitPrice * 1.02'))
Note that to target each of the elements of an array, instead of the array
itself, you must explicitly include
[*]
after the name of the targeted field whose value is the array —
there is no implicit iteration. You can target the array itself (for example
'$.employees'
) if, in a scoped operation, you want to refer to
specific array elements, such as the third element, @[2]
, but this is
not a common use case.
You cannot use $
in the LHS of an operation
in a nested-path scope; you must use @
instead. This is another way of
saying that the transformation/modification for a nested scope is limited to that scope;
the operations performed cannot act outside it.
You can, however, use $
in the RHS of a scoped
operation. For example, this code first gives each employee a raise of 10%
(*
factor 1.1
), and then assigns each employee the
same bonus, which is the value of $.department.bonus
.
json_transform(data,
NESTED PATH '$.employees[*]'
(SET '@.salary' = PATH '@.salary * 1.1',
SET '@.bonus' = PATH '$.department.bonus'))
Occurrences of $
in the RHS of a scoped operation always
refer to the topmost (outermost) context of the json_transform
invocation.
Within a nested operation (to reiterate):
-
@
refers to the data targeted by the nested path. -
$
refers to the topmost (outermost) context item, and it can only be used in the RHS of an operation.
Example 13-21 Downscoping with NESTED PATH, To Limit JSON_TRANSFORM Pruning by KEEP
This example limits the scope of a KEEP
operation to a
specific nested path. Data outside that scope is not pruned. The result is
that only elements of array LineItems
have all fields other than
UnitPrice
and Quantity
removed.
json_transform(data,
NESTED PATH '$.LineItems[*]'
(KEEP '@.Part.UnitPrice', '@.Quantity'))
Example 13-22 JSON_TRANSFORM: Using NESTED PATH To Aggregate Over Array Elements
This example transforms all documents in
j_purchaseorder.data
on the fly, to add a new field,
OrderTotal
, which is the cost of all line-item entries in a
purchase order. It does this by first calculating the cost of each line item and
then summing those costs. The line-item costs are added to the line-item objects in
a new field that is removed after those item costs are summed to produce the order
total.
These are the operations performed, in order:
-
Use operation
NESTED PATH
with operationSET
, to add a new field,LineItemTotal
, which is calculated from the unit price, to each element of arrayLineItems
. -
Use operation
SET
to add a new top-level field,OrderTotal
, whose value is the sum of all of theLineItemTotal
values. -
Use operation
REMOVE
to remove theLineItemTotal
fields from the line items.
Note that this is only a SELECT
operation; the example
does not store the transformed documents in j_purchaseorder.data
.
For that, you would use an UPDATE
statement.
SELECT json_transform(
data,
NESTED PATH '$.LineItems[*]'
(SET '@.LineItemTotal' = PATH '@.Part.UnitPrice * @.Quantity'),
SET '$.OrderTotal' = PATH '$.LineItems[*].LineItemTotal.sum()',
REMOVE '$.LineItems[*].LineItemTotal')
FROM j_purchaseorder;
No handlers are allowed for operator NESTED PATH
.
Parent topic: Oracle SQL Function JSON_TRANSFORM