Data Transformation with JMESPath

I’ve a hate/love relationship with JavasScript in the Function nodes. I love it because it’s powerful, and I hate it because it’s far from intuitive and user friendly. Especially, when you compare this to how relatively easy it is to build expressions in other nodes.

Therefor, I’ve decided to try to figure out which common Javascript functions can be converted to JMESPath’s JSON query language. Currently, when building these queries, I use the following approach:

  • create a Function Node
  • first only fetch the json that I’m going to work on via return items, item, $node[‘xyz’].json, etc.
  • copy the JSON value
  • paste the JSON into https://jsonparser.org
  • click the JSON Parser → button Screenshot 2022-04-02 at 08.17.13 in the middle to get the tree on the right
  • click the filter Screenshot 2022-04-02 at 08.18.25 icon to open the wizard to start building the query
  • once the query does what I want, I then use it in the $jmespath function in the Function Node
return $jmespath(items, "FUNCTION")

And voila!

Please note that you need a recent version of n8n, as JMESPath is n8n is relatively new.

P.S.: and now that I thing of it: perhaps it would be nice to have the jsonparser functionality in n8n :sunglasses:

3 Likes

And some sample code …

Once I started to build more complex queries, like

"rss.channel.item[]|[?contains(description,'Stuttgart')]||[?contains(description,'Berlin')].{description: description}"

I decided it was time to break thing down to make it more readable

let query = "rss.channel.item[]" // filter JSON down to item array

query += "|" // pipe expression > pipe expression into subsequent expressions
query += "[?contains(description,'Stuttgart')]" // search for Stuttgart in description
query += "||" // or expression
query += "[?contains(description,'Berlin')]" // search for Berlin in description
query += ".{description: description}" // return key value pair "description": "description"

return $jmespath(item, query)

And yes … I’ve currently got way too much spare time … but that will change soon when the weather gets better and my mountainbike is taking me into the mountains again :sunglasses:

1 Like

And here an JMESPath alternative to JavaScript for the following challenge Function node doesn't accept returned array

The Javascript code is:

const valueToFind=248103;
for (let i=0; i < items[0].json.length; i++)
  if (items[0].json[i].field_id == valueToFind)
    return [{json: {id: items[0].json[i].id}}];
return [{json: {}}] // Didn't find anything, so return empty item

And the JMESPath query is:

return $jmespath(item, "[?field_id==`249841`].{id: id}[0]")
1 Like