Запрос JMESPath для вложенных структур массива

У меня есть следующая структура данных в результате журналов aws get-query-results:

    {
    "status": "Complete", 
    "statistics": {
        "recordsMatched": 2.0, 
        "recordsScanned": 13281.0, 
        "bytesScanned": 7526096.0
    }, 
    "results": [
        [
            {
                "field": "time", 
                "value": "2019-01-31T21:53:01.136Z"
            }, 
            {
                "field": "requestId", 
                "value": "a9c233f7-0b1b-3326-9b0f-eba428e4572c"
            }, 
            {
                "field": "logLevel", 
                "value": "INFO"
            }, 
            {
                "field": "callerId", 
                "value": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
            }
        ],
        [
            {
                "field": "time", 
                "value": "2019-01-25T13:13:01.062Z"
            }, 
            {
                "field": "requestId", 
                "value": "a4332628-1b9b-a9c2-0feb-0cd4a3f7cb63"
            }, 
            {
                "field": "logLevel", 
                "value": "INFO"
            }, 
            {
                "field": "callerId", 
                "value": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
            }
        ],
      ]
    }

Интерфейс командной строки AWS поддерживает язык JMESPath для фильтрации вывода. Мне нужно применить строку запроса, чтобы отфильтровать среди возвращенных «результатов» объекты, содержащие «callerId» в качестве «поля», получить свойство «значение» и получить следующий результат:

    [
      {
       callerId: "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
      },
      {
       callerId: "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
      }
    ]

Первый шаг, который я делаю, - это выравнивание массива результатов строкой запроса: results[]

При этом будут считаны другие корневые свойства (статус, статистика) и будет возвращен только один большой массив со всеми похожими объектами {field: ..., value: ...}. Но после этого мне не удается правильно отфильтровать те объекты, которые соответствуют полю == "callerId". Я безуспешно пробовал, среди прочего, следующие выражения:

'results[][?field=="callerId"]'
'results[][*][?field=="callerId"]'
'results[].{ callerId: @[?field=="callerId"].value }'

Я не эксперт в JMESPath, и я изучал руководства на сайте jmespath.org, но не смог заставить его работать.

Спасибо!


person fjf    schedule 27.05.2019    source источник
comment
удалите последнюю запятую, если вы поместите свой json в тестер пути JMES, код не будет работать   -  person bosskay972    schedule 17.07.2019


Ответы (2)


Использование jq - это хорошо, потому что это более полный язык, но если вы хотите сделать это с помощью JMES Path, вот решение:

results[*][?field=='callerId'].{callerId: value}[]

получить:

[
  {
    "callerId": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
  },
  {
    "callerId": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
  }
]
person bosskay972    schedule 17.07.2019

Я не могу воспроизвести полностью, поскольку у меня нет тех же журналов в моем потоке журналов, но я смог сделать это с помощью jq и поместив образец объекта JSON в файл

cat sample_output.json | jq '.results[][] | select(.field=="callerId") | .value'

ВЫВОД:

"a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
"a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"

вы можете направить вывод из aws cli в jq.

Мне удалось довольно близко познакомиться с собственным запросом JMESPath и встроенным редактором на этом сайте http://jmespath.org/examples.html#filtering-and-selecting-nested-data

results[*][?field==`callerId`][]

ВЫВОД:

[
  {
    "field": "callerId",
    "value": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
  },
  {
    "field": "callerId",
    "value": "a9b0f9c2-eb42-3986-33f7-8e450b1b72cf"
  }
]

но я не уверен, как сделать callerId ключом, а значение - значением другого ключа.

person jmp    schedule 29.06.2019
comment
спасибо @jmp, в какой-то момент я получил что-то очень похожее, но, к сожалению, требования меня просили только JMESPath. - person fjf; 11.09.2019