{"id":2896,"date":"2022-07-20T08:39:05","date_gmt":"2022-07-20T08:39:05","guid":{"rendered":"https:\/\/info.documotor.com\/?page_id=2896"},"modified":"2023-05-01T12:30:46","modified_gmt":"2023-05-01T12:30:46","slug":"context-operators-vs-parent-and-pipe","status":"publish","type":"page","link":"https:\/\/info.documotor.com\/?page_id=2896","title":{"rendered":"Context Operators"},"content":{"rendered":"\n<p>This guide will describe how we can use a range of different operators within our transformations to change the context of the data which we are transforming. The default context is within the payload data, but this can be changed instead to data created previously in the transformation.<\/p>\n\n\n\n<p>Note that a sample payload has been included <a href=\"https:\/\/info.documotor.com\/?page_id=2896#section_5\">here<\/a> at the bottom of the page for you to use in exploring the transformations included here.<\/p>\n\n\n\n<h2>Current Node &#8211; @<\/h2>\n\n\n\n<p>Throughout the guides and tutorials on this site, you may see references to the <strong><code>@<\/code><\/strong> symbol. This is defined by JMESPath as the <a href=\"https:\/\/jmespath.org\/specification.html?highlight=current%20node#current-node\">&#8216;current node&#8217;<\/a>. The current node is the point in the payload that our transformation is currently referring to. To illustrate this, consider the sample data at the end of this guide. Here we can use the current node to assign the entire payload to a single data point:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  \"Data\": @\n}<\/code><\/pre>\n\n\n\n<p>This results in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n  \"Data\": {\n    \"Globals\": {\n\t...\n    },\n    \"SalesData\": [\n      {\n        \"Date\": \"4\/1\/21\",\n        \"Region\": \"Denmark\",\n        \"SalesRep\": \"S. Ehlers\",\n        \"Product\": \"Template\",\n        \"Units\": \"99\",\n        \"PricePerUnit\": \"52.99\",\n        \"TotalCost\": \"5246.01\"\n      },\n\t...\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<h2>Evaluating data using the current node<\/h2>\n\n\n\n<p>We can also use the current node operator to evaluate our data. In our sample data, <code>SalesData<\/code> is an array of 11 different objects, each of which includes a <code>TotalCost <\/code>value. The following simple transformation allows us to create a single object to contain both our minimum and maximum values. As <code>SalesData<\/code> has been defined in the first line as the context for the object, we can simply use the current node operator to refer to this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  min_max: SalesData.{\n    max: max_by(@, &amp;TotalCost),\n    min: min_by(@, &amp;TotalCost)\n  }\n}<\/code><\/pre>\n\n\n\n<p>The following more complex transformation shows an example of the current node being referred to a number of times to produce a result. In this case, the result is essentially the same as in the first example but includes the addition of an index key onto each object within <code>SalesData<\/code> to allow for a unique identifier to be added. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  data: sort_by(SalesData[*] | map(&amp;merge(@,{__index: __index}), @), &amp;TotalCost).{\n    min: @[0],\n    max: @[-1]\n  }\n}<\/code><\/pre>\n\n\n\n<p>Note the use of the pipe expression on the first line. You can find an explanation of this <a href=\"https:\/\/info.documotor.com\/?page_id=2896#section_4\">here<\/a>. The current node is used in four different instances:<\/p>\n\n\n\n<ul><li>As part of the <a href=\"https:\/\/jmespath.org\/specification.html?highlight=map#map\">map function<\/a> that allows us to apply a transformation to each object in the array.<\/li><li>As part of the <a href=\"https:\/\/jmespath.org\/specification.html?highlight=map#merge\">merge function<\/a> which is the function being applied to each object and adds the index value.<\/li><li>As part of the definition for max and min. In this case, sort the array by <code>TotalCost <\/code>then select the first and last objects.<\/li><\/ul>\n\n\n\n<h2>The $ operator<\/h2>\n\n\n\n<p>Sometimes it is convenient to refer to already transformed data rather than repeating the same transformation. The <code>$<\/code> operator allows us to be able to do this. In the below example, you can see the <code>$<\/code> operator being used to <a href=\"https:\/\/info.documotor.com\/?page_id=282#subtract\">subtract<\/a> the previously transformed minimum value from the maximum value.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  data: sort_by(SalesData[*] | map(&amp;merge(@,{__index: __index}), @), &amp;TotalCost).{\n    min: @[0],\n    max: @[-1]\n  },\n  totalCostSpread: subtract($.data.\"max\".TotalCost, $.data.\"min\".TotalCost)\n}<\/code><\/pre>\n\n\n\n<p>NOTE, the <code>$<\/code> operator will only work on data points that have <em>previously<\/em> been defined in the transformation. For example, if <code>totalCostSpread<\/code> was defined before <code>data<\/code>, then this transformation would fail. Aside from this restriction, all other transformations can be applied to data as normal.<\/p>\n\n\n\n<h2>Parent<\/h2>\n\n\n\n<p>It is sometimes necessary to include data from multiple nodes that exist on the same or higher levels in the payload. There are a number of ways to achieve this depending on how the data is structured. One way is to use the <code>parent<\/code> operator. In the example below we extend the <code>min_max<\/code> object we created earlier to include the date from our <code>Globals<\/code> data point. We use parent here because the <code>min_max<\/code> object refers to the <code>SalesData<\/code> array which is on the same level in the data as <code>Globals<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  min_max: SalesData.{\n    max: max_by(@, &amp;TotalCost),\n    min: min_by(@, &amp;TotalCost),\n    reportDate: parent(@).Globals.Date\n  }\n}<\/code><\/pre>\n\n\n\n<p>The result here is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  \"min_max\": {\n    \"max\": {\n      \"Date\": \"7\/21\/21\",\n      \"Region\": \"Ireland\",\n      \"SalesRep\": \"J. Hansen\",\n      \"Product\": \"Template\",\n      \"Units\": \"79\",\n      \"PricePerUnit\": \"86.99\",\n      \"TotalCost\": \"6872.21\"\n    },\n    \"min\": {\n      \"Date\": \"4\/28\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"E. McKenna\",\n      \"Product\": \"Template\",\n      \"Units\": \"63\",\n      \"PricePerUnit\": \"49.99\",\n      \"TotalCost\": \"3149.37\"\n    },\n    \"reportDate\": \"01\/02\/2020\"\n  }\n}<\/code><\/pre>\n\n\n\n<p>NOTE that <code>parent<\/code> can be used to go back as far in the data structure as required by nesting it. For example <code>parent(parent(parent(@)))<\/code> will allow you to go back three levels within the payload. Similarly, <code>parent(parent(parent($)))<\/code> will allow you to go back three levels within already transformed data.<\/p>\n\n\n\n<h2>The pipe (&#8220;|&#8221;) operator<\/h2>\n\n\n\n<p>The pipe operator is JMESPath functionality that allows us to make a transformation, then use the result of that transformation as the basis of a new transformation. The basic concept is that whatever is the result of the left-hand side of the pipe operator becomes the data used for the transformation on the right-hand side of the pipe operator and can be referred to using the <code>@<\/code> operator. More information on the pipe can be found on the <a href=\"https:\/\/jmespath.org\/examples.html?highlight=pipe#pipes\">JMESPath site here<\/a>. In the example below, we are using the operator in the first line of our transformation to set the <code>SalesData<\/code> array as our current node (left side of the operator). This is then referred to in the map and merge functions (right side of the operator). <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{\n  data: sort_by(SalesData[*]|map(&amp;merge(@,{__index: __index}), @), &amp;TotalCost).{\n    min: @[0],\n    max: @[-1]\n  }\n}<\/code><\/pre>\n\n\n\n<h2>Sample Data<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n  \"Globals\": {\n    \"Date\": \"01\/02\/2020\",\n    \"Region\": \"Global\"\n  },\n  \"SalesData\": [\n    {\n      \"Date\": \"4\/1\/21\",\n      \"Region\": \"Denmark\",\n      \"SalesRep\": \"S. Ehlers\",\n      \"Product\": \"Template\",\n      \"Units\": \"99\",\n      \"PricePerUnit\": \"52.99\",\n      \"TotalCost\": \"5246.01\"\n    },\n    {\n      \"Date\": \"2\/7\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"M. Priesler\",\n      \"Product\": \"Documotor\",\n      \"Units\": \"66\",\n      \"PricePerUnit\": \"50.99\",\n      \"TotalCost\": \"3365.34\"\n    },\n    {\n      \"Date\": \"2\/24\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"E. McKenna\",\n      \"Product\": \"Template\",\n      \"Units\": \"51\",\n      \"PricePerUnit\": \"82.99\",\n      \"TotalCost\": \"4232.49\"\n    },\n    {\n      \"Date\": \"3\/20\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"M. Rafn\",\n      \"Product\": \"Addin\",\n      \"Units\": \"60\",\n      \"PricePerUnit\": \"74.99\",\n      \"TotalCost\": \"4499.4\"\n    },\n    {\n      \"Date\": \"5\/5\/21\",\n      \"Region\": \"Ireland\",\n      \"SalesRep\": \"B. Sigurdsson\",\n      \"Product\": \"Template\",\n      \"Units\": \"82\",\n      \"PricePerUnit\": \"68.99\",\n      \"TotalCost\": \"5657.18\"\n    },\n    {\n      \"Date\": \"6\/27\/21\",\n      \"Region\": \"Denmark\",\n      \"SalesRep\": \"S. Ehlers\",\n      \"Product\": \"Documotor\",\n      \"Units\": \"95\",\n      \"PricePerUnit\": \"45.99\",\n      \"TotalCost\": \"4369.05\"\n    },\n    {\n      \"Date\": \"1\/19\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"M. Mortensen\",\n      \"Product\": \"Template\",\n      \"Units\": \"64\",\n      \"PricePerUnit\": \"86.99\",\n      \"TotalCost\": \"5567.36\"\n    },\n    {\n      \"Date\": \"4\/28\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"E. McKenna\",\n      \"Product\": \"Template\",\n      \"Units\": \"63\",\n      \"PricePerUnit\": \"49.99\",\n      \"TotalCost\": \"3149.37\"\n    },\n    {\n      \"Date\": \"7\/21\/21\",\n      \"Region\": \"Ireland\",\n      \"SalesRep\": \"J. Hansen\",\n      \"Product\": \"Template\",\n      \"Units\": \"79\",\n      \"PricePerUnit\": \"86.99\",\n      \"TotalCost\": \"6872.21\"\n    },\n    {\n      \"Date\": \"2\/8\/21\",\n      \"Region\": \"Denmark\",\n      \"SalesRep\": \"S. Ehlers\",\n      \"Product\": \"Documotor\",\n      \"Units\": \"77\",\n      \"PricePerUnit\": \"62.99\",\n      \"TotalCost\": \"4850.23\"\n    },\n    {\n      \"Date\": \"1\/17\/21\",\n      \"Region\": \"Germany\",\n      \"SalesRep\": \"K. Vagsheyg\",\n      \"Product\": \"Template\",\n      \"Units\": \"55\",\n      \"PricePerUnit\": \"93.99\",\n      \"TotalCost\": \"5169.45\"\n    }\n  ]\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide will describe how we can use a range of different operators within our transformations to change the context of the data which we are transforming. The default context is within the payload data, but this can be changed instead to data created previously in the transformation. Note that a sample payload has been [&hellip;]<\/p>\n","protected":false},"author":11,"featured_media":0,"parent":2252,"menu_order":3,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/pages\/2896"}],"collection":[{"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/info.documotor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2896"}],"version-history":[{"count":21,"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/pages\/2896\/revisions"}],"predecessor-version":[{"id":5478,"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/pages\/2896\/revisions\/5478"}],"up":[{"embeddable":true,"href":"https:\/\/info.documotor.com\/index.php?rest_route=\/wp\/v2\/pages\/2252"}],"wp:attachment":[{"href":"https:\/\/info.documotor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2896"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}