JMESPath示例

JMESPath中包含许多示例。如果您是JMESPath新手,可以从 JMESPath教程 ,它介绍了JMESPath的基础知识。

注解

你有什么要补充的例子吗?发送 pull request 在github上。你想看看这里没有的例子吗?打开一个 issue on github .

过滤器和多选列表

JMESPath最常见的使用场景之一是能够获取复杂的JSON文档并将其简化。这里的主要功能是过滤器和多重选择。在下面的示例中,我们使用people数组,对于任何具有age key且值大于20的元素,我们将创建name和age值的子列表。


        

过滤器和多选散列

在前面的例子中,我们使用了一个散列数组,并将其简化为一个包含名称和年龄的两个元素数组的数组。我们也只包括列表元素 age 键大于 20 . 如果我们想创建相同的哈希结构,但只包含 agename key,我们可以说:


        

上面表达式的后半部分包含具有一般形式的键值对 keyname: <expression> . 在上面的表达式中,我们只是使用一个字段作为表达式,但是它们可以是更高级的表达式。例如:


        

注意在上面的示例中,而不是应用过滤器表达式 ([? <expr> ] ),我们正在通过 [*] .

使用嵌套数据


        

上面的示例结合了几个JMESPath特性,包括flatten操作符、multiselect列表、过滤器和管道。

输入数据包含一个顶级键“reservations”,它是一个列表。在每个列表中,都有一个“实例”键,它也是一个列表。

我们要做的第一件事是从多个实例列表中创建一个列表。通过使用 展平运算符 我们可以将第一个列表中的两个实例和第二个列表中的两个实例合并为一个列表。尝试将上述表达式更改为just reservations[].instances[] 看看这个扁平列表的外观。一切都是对的 reservations[].instances[] 是关于获取扁平化的列表,并将其精简以仅包含我们需要的数据。这个表达式获取原始列表中的每个元素并将其转换为一个三元素子列表。这三个要素是:

  • tags 列表中,选择展开的第一个元素 Values 列出谁的 Key 具有一定的价值 Name .

  • 这个 type

  • 这个 state.name 每一个实例。

这三个表达式中最有趣的是 tags[?Key=='Name'].Values[] | [0] 部分。让我们进一步研究一下。

首先要注意的是我们正在筛选与 tags 钥匙。这个 tags[?Key==`Name`] 告诉我们只包含包含 Key 其价值是 Name . 从这些筛选的列表元素中,我们将使用 Values 键并展开列表。最后 | [0] 将获取整个列表并提取第0个元素。

筛选和选择嵌套数据

在这个例子中,我们将研究如何过滤嵌套哈希。


        

在本例中,我们搜索 people 数组。此数组中的每个元素都包含两个元素的哈希,哈希中的每个值本身都是哈希。我们试图检索 general 包含 id 值为的键 100 .

如果我们有这个表情 people[?general.id==`100`] ,我们得到的结果是:

[{
  "general": {
    "id": 100,
    "age": 20,
    "other": "foo",
    "name": "Bob"
  },
  "history": {
    "first_login": "2014-01-01",
    "last_login": "2014-01-02"
  }
}]

Let's walk through how we arrived at this result. In words, the people[?general.id==`100`] expression is saying "for each element in the people array, select the elements where the general.id equals 100". If we trace the execution of this filtering process we have:

# First element:
    {
      "general": {
        "id": 100,
        "age": 20,
        "other": "foo",
        "name": "Bob"
      },
      "history": {
        "first_login": "2014-01-01",
        "last_login": "2014-01-02"
      }
    },
# Applying the expression ``general.id`` to this hash::
    100
# Does 100==100?
    true
# Add this first element (in its entirety) to the result list.

# Second element:
    {
      "general": {
        "id": 101,
        "age": 30,
        "other": "bar",
        "name": "Bill"
      },
      "history": {
        "first_login": "2014-05-01",
        "last_login": "2014-05-02"
      }
    }

# Applying the expression ``general.id`` to this element::
    101
# Does 101==100?
    false
# Do not add this element to the results list.
# Result of this expression is a list containing the first element.

但是,这仍然不是我们想要的最终值,即:

{
  "id": 100,
  "age": 20,
  "other": "foo",
  "name": "Bob"
}

为了从过滤后的结果中得到这个值,我们需要首先选择 general 钥匙。这为我们提供了一个 general 搞砸::

[{
  "id": 100,
  "age": 20,
  "other": "foo",
  "name": "Bob"
}]

从那里,我们用一根管子 (| )停止投影以便最终选择第一个元素 ([0] ). 请注意,我们假设只有一个哈希包含 id 属于 100 . 考虑到数据的结构方式,完全有可能获得如下数据:

{
  "people": [
    {
      "general": {
        "id": 100,
        "age": 20
      },
      "history": {
      }
    },
    {
      "general": {
        "id": 101,
        "age": 30
      },
      "history": {
      }
    },
    {
      "general": {
        "id": 100,
        "age": 30
      },
      "history": {
      }
    }
  ]
}

注意这里的第一个和最后一个元素 people 数组都有一个 id 属于 100 . 然后我们的表达式将选择第一个匹配的元素。

最后,值得一提的是,写这个表达式的方法不止一种。在这个例子中,我们决定在过滤列表之后,选择 general 键,然后选择该列表中的第一个元素。我们也可以颠倒这些操作的顺序,我们可以获取过滤列表,选择第一个元素,然后提取与 general 钥匙。这个表达式应该是:

people[?general.id==`100`] | [0].general

两个版本同样有效。

使用函数

JMESPath functions 在使用JMESPath表达式时,为您提供了强大的功能和灵活性。下面是JMESPath中使用的一些常见表达式和函数。

sort_by


        

这里第一个有趣的功能是 sort_by . 在本例中,我们对 Contents 按每个值排列 LastModified 在中输入每个元素 Contents 数组。这个 sort_by 函数接受两个参数。第一个参数是一个数组,第二个参数描述应该用来对数组排序的键。

这个表达式中第二个有趣的地方是第二个参数以 & ,创建表达式类型。从概念上来说,这是对表达式的引用,以后可以对其求值。如果您熟悉lambda和匿名函数,则表达式类型是相似的。我们使用的原因 &LastModified 而不是 LastModified 因为如果表达式是 LastModified ,将在调用函数之前对其进行求值,并且假定没有 LastModified 在外部哈希中,第二秒将计算为 null . 退房 功能评价 有关如何在JMESPath中计算函数的详细信息,请参阅。另外,请注意,我们利用了这样一个事实,即日期是ISO8601格式的,可以按字典顺序排序。

最后,这个表达式中最后一个有趣的地方是 [*] 紧接着 sort_by 函数调用。这样做的原因是我们希望将multiselect散列(表达式的后半部分)应用于排序数组中的每个元素。为了做到这一点,我们需要一个投影。这个 [*] 正是这样做的,它接受输入数组并创建一个投影,以便multiselect散列 {{Key: Key, Size: Size}} 将应用于列表中的每个元素。

还有其他函数的表达式类型类似于 sort_by 包括 min_bymax_by .

管道表达式对于停止投影非常有用。它们也可以用来分组表达式。

主页面

让我们看看 JMESPath front page .


        

我们可以将这个JMESPath表达式看作有三个组件,每个组件由管道字符分隔 | . 我们熟悉第一个表达式,它与本页的第一个示例类似。表达的第二部分, sort(@) ,类似于 sort_by 我们在上一节中看到的函数。这个 @ token用于引用当前元素。这个 分类 函数接受一个数组参数。如果输入的JSON文档是散列,并且我们希望对 foo 键,它是一个数组,我们可以使用 sort(foo) . 在这个场景中,输入JSON文档就是我们要排序的数组。为了引用这个值,我们使用当前元素, @ ,表示这一点。我们也只取排序数组的一个子集。我们用的是切片 ([-2:] )以指示我们只希望排序数组中的最后两个元素传递到此表达式的最后三分之一。

最后,表达的第三部分, {{WashingtonCities: join(', ', @)}} ,创建多选择哈希。它将排序后的城市名称列表作为输入,生成一个只有一个键的散列, WashingtonCities ,其值是输入列表(用 @ )以逗号分隔的字符串。