嵌套数组结构的JMESPath查询

时间:2019-05-27 07:36:38

标签: arrays json multidimensional-array aws-cli 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 CLI支持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 个答案:

答案 0 :(得分:1)

由于日志流中没有相同的日志,所以我无法完全复制,但是我可以使用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用作键,并将值作为另一个键的值。

答案 1 :(得分:0)

使用jq是一件好事,因为它是更完整的语言,但是如果您想在此处使用JMES Path来实现,则解决方案:

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

获得:

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