Search code examples
node.jsjmespath

Chaining filters in JMESpath


I want to be able to chain together multiple filters using JMESpath but it appears you cannot filter on the output of a filter.

My working example is as follows:

// document:
{
  pips: {
    ancestors:[{
      id: 'p01234567'
    }],
    episode: {
      more: 'data',
      goes: 'here
    }
  }
}
// working filter: `[pips][?ancestors[?pid=='p01234567'] && episode]`

But I would like to write my filter instead as follows, effectively to filter the output of another filter:

[pips][?ancestors[?pid=='p01234567']][?episode]

Any idea why this doesn't work?

I am building this in NodeJS using the following NPM package: https://www.npmjs.com/package/jmespath Is there a mistake in the syntax I am using, is there a bug in the library I am using, or am I just trying to do something that is outside what JMESpath allows?

Thank you!


Solution

  • I found the reason why - projections are evaluated in two steps, with the left-hand-side creating a JSON array of initial values and the right-hand-side is the expression.

    Solution: "Pipe expressions" which allow you to"operate on the result of a projection".

    So instead of the incorrect expression from before: [pips][?ancestors[?pid=='p01234567']][?episode]

    This instead should be written as: [pips][?ancestors[?pid=='p01234567']] | [?episode]

    And to undo the conversion of the initial document into an array, we can convert this back to an object like this: [pips][?ancestors[?pid=='p01234567']] | [?episode] | [0]

    As a side note, I observed that using parentheses () also works, but using pipes are a bit cleaner.