Jmespathの使用例を記載してみました

## 概要

- 知っていると便利だと思うjmespathの使用方法を記載しています

## TL;DR

- 公式の[チュートリアル][2]や[Example][3]がわかりやすいです
- 条件にマッチするものを取得する場合のクエリ条件
  - ``"?<key>==`<取得したい値`>"``
- 平坦化する場合は基本的に``<クエリ条件> | []``
- [Built-in Functions][1]
  - 使える関数
    - abs
    - avg
    - contains
    - ceil
    - floor
    - join
    - keys
    - length
    - max
    - min
    - sort
    - to_string
    - to_number
    - type
    - values
  - ポイント
    - ``.<functions>(@)``と記載する

## 準備

### jmespathをinstallする

- ``pip install jmespath``を実行する

### sample data

```json
{
  "test": [
    {
      "id": 1,
      "name": "A",
      "color": "red"
    },
    {
      "id": 2,
      "name": "B",
      "color": "blue"
    },
    {
      "id": 3,
      "name": "C",
      "color": "red"
    }
  ],
  "sample":[
    {
      "id": 1,
      "name": "D",
      "type": "fire"
    },
    {
      "id": 2,
      "name": "E",
      "type": "water"
    },
    {
      "id": 3,
      "name": "F",
      "type": "water"
    }
  ]
}
```

## 構文

### 基本的な構文

- ``jmespath.search("<クエリ条件>", <検索したい変数>)``
  - ``jmespath.search()``の()の中にクエリ条件と変数を記載する
  - クエリ条件は``""(ダブルクォーテーション)``でくくる
  - クエリ条件のあとに``,(カンマ)``を記載し変数を記載する

### 全ての値を取得する

- クエリ条件を``*(アスタリスク)``を使用する
  - ``jmespath.search("*", <検索したい変数>)``

### 条件にマッチした値を取得する

- クエリ条件：``"test[?color==`red`]"``
  - listの中で``"?<key>==`<取得したい値`>"``と記述する
- ポイント
  - 条件式は``?``で始める
  - 取得したい値は`` ` `(バッククォーテーション)``で囲む
  - listの中に書く

## 使用例

- 使用例は、sample dataを使っています。

### listの中身を取得する

- クエリ条件
  - ``jmespath.search("test[]",data)``
    - ``test``を``sample``に置き換えれば``sample``配下のlistが取れます。

- 出力結果

```json
[
  {”id”: 1, ”name”: ”A”, ”color”: ”red”
  },
  {”id”: 2, ”name”: ”B”, ”color”: ”blue”
  },
  {”id”: 3, ”name”: ”C”, ”color”: ”red”
  }
]
```

---

### nameだけ取得する

- クエリ条件
  - ``jmespath.search("test[].name",data)``

- 出力結果

```json
[”A”, ”B”, ”C”]
```

#### 全てのnameを取得する

- クエリ条件
  - ``jmespath.search("*[].name",data)``
    - ``"*[].name"``の``.name``を``id``や``color``にすることで取得できる値を変えることができます。

- 出力結果

```json
[”A”, ”B”, ”C”, ”D”, ”E”, ”F”]
```

---

### 条件にマッチした値の情報を取得する

- クエリ条件
  - ``jmespath.search("test[?color==`red`]",data)``

- 出力結果

```json
[
  {”id”: 1, ”name”: ”A”, ”color”: ”red”
  },
  {”id”: 3, ”name”: ”C”, ”color”: ”red”
  }
]
```

#### 条件にマッチした値を取得し、特定の値を出力する

- クエリ条件
  - ``jmespath.search("sample[?type==`water`].name",data)``

- 出力結果

```json
[”E”, ”F”]
```

---

### 取得した値の要素数を数える

#### typeがarrayの場合

- クエリ条件
  - ``jmespath.search("sample.length(@)",data)``

- 出力結果

```json
3
```

- ``length(@)``がない場合の出力

```json
[
  {”id”: 1, ”name”: ”D”, ”type”: ”fire”
  },
  {”id”: 2, ”name”: ”E”, ”type”: ”water”
  },
  {”id”: 3, ”name”: ”F”, ”type”: ”water”
  }
]
```

#### typeがobjectの場合

- クエリ条件
  - ``jmespath.search("sample[].length(@)",data)``
- 出力結果

```json
[3, 3, 3]
```

```json
[
  {”id”: 1, ”name”: ”D”, ”type”: ”fire”
  },
  {”id”: 2, ”name”: ”E”, ”type”: ”water”
  },
  {”id”: 3, ”name”: ”F”, ”type”: ”water”
  }
]
```

---

### typeを確認する

#### arrayの場合

- クエリ条件
  - ``jmespath.search("sample.type(@)",data)``
- 出力結果

```json
”array”
```

#### objectの場合

- クエリ条件
  - ``jmespath.search("sample.type(@)",data)``
- 出力結果

```json
[”object”]
```

---

### keyだけ取得する

- クエリ条件
  - ``jmespath.search("sample[].keys(@)",data)``

- 出力結果

```json
[
  [”id”, ”name”, ”type”
  ],
  [”id”, ”name”, ”type”
  ],
  [”id”, ”name”, ”type”
  ]
]
```

---

### 投影する

- クエリ条件
  - ``jmespath.search("*[*].name",data)``
    - (正確な表現ではないかもしれませんが)元々の形を維持したまま出力する
- 出力結果

```json
[[”A”, ”B”, ”C”], [”D”, ”E”, ”F”]]
```

---

### 平坦化する

- クエリ条件
  - ``jmespath.search("*[*].name | []",data)`` もしくは``jmespath.search("*[*].name[]",data)``
    - listがネストしているものを平坦化している

```json
[”A”, ”B”, ”C”, ”D”, ”E”, ”F”]
```

## 最後に

- 本記事を読んでいただきありがとうございます。
- 個人的にjmespathで便利そうな使用例を記載しました。  
  正確でない表現や意味が間違っている箇所がありましたら、ご指摘していただきたいです。
- jmespathを学ぶことでjson形式のデータを簡単に扱えるようになったと感じています。  
  本記事を参考にしていただけると幸いです。

##  参考

- https://jmespath.org/
- https://jmespath.org/tutorial.html
- https://jmespath.org/examples.html
- https://jmespath.org/proposals/functions.html

[1]: https://jmespath.org/proposals/functions.html
[2]: https://jmespath.org/tutorial.html
[3]: https://jmespath.org/examples.html