yaml-jsonpath icon indicating copy to clipboard operation
yaml-jsonpath copied to clipboard

Filter expression on array with combined logical operators

Open rspurgeon opened this issue 1 year ago • 2 comments

Describe the bug

The library supports existence filtering expressions on arrays with simple values. For example the following is validated in the web application:

input.yaml

services:
- host: api.example.com
  routes:
  - methods:
    - POST
    name: create
  - methods:
    - GET
    name: get
  - methods:
    - OPTIONS
    - GET
    name: getopt

Expression:

$.services[*].routes[?(@.methods[?(@=='GET')])]

Returns:

methods:
  - GET
name: get
---
methods:
  - OPTIONS
  - GET
name: getopt

However, I cannot determine if the inner most expression can be combined with an && or || operator to check for the existence of all or any values within an array.

Various expressions have been tried including:

$.services[*].routes[?(@.methods[?(@=='GET')] && @.methods[?(@=='OPTIONS')])]

Results:

Invalid JSON path: invalid path syntax at position 45, following ")]"

Is it possible to combine these array existence filters?

Reproduction steps

  1. Start the web application as instructed: https://github.com/vmware-labs/yaml-jsonpath/blob/main/web/README.md
  2. Use the input value:
services:
- host: api.example.com
  routes:
  - methods:
    - POST
    name: create
  - methods:
    - GET
    name: get
  - methods:
    - OPTIONS
    - GET
    name: getopt
  1. Use the filter:
$.services[*].routes[?(@.methods[?(@=='GET')] || @.methods[?(@=='POST')])]

...

Expected behavior

Combining other filters appears to be supported, so I would expect this filter to return both the array items that contain a GET OR a POST operation.

Additional context

No response

rspurgeon avatar Oct 24 '24 20:10 rspurgeon

Verified this query should work using another jsonpath implementation and the same document in json form VS yaml: $.services[*].routes[?(@.methods=='GET' || @.methods=='POST')] , but does not work here. Confirmed there is no response.

I see this behavior also with only 1 query (not a combo with the or (||) operator: $.services[*].routes[?(@.methods=='GET')]

ahuffman avatar Oct 25 '24 14:10 ahuffman

After further testing I was able to get the desired query with $.services[*].routes[?(@.methods[?(@ == "GET" || @ == "POST")])], which returns:

methods:
  - POST
name: create
---
methods:
  - GET
name: get
---
methods:
  - OPTIONS
  - GET
name: getopt

ahuffman avatar Oct 25 '24 14:10 ahuffman