Запрос JMESPath для структур вложенных массивов - PullRequest
1 голос
/ 27 мая 2019

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

    {
    "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"
            }
        ],
      ]
    }

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

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

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

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

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

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

Спасибо!

Ответы [ 2 ]

1 голос
/ 29 июня 2019

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

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

OUTPUT :

"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`][]

OUTPUT :

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

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

0 голосов
/ 17 июля 2019

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

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

, чтобы получить:

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