前陣子在看AWS文件的時候意外發現這個神奇的工具,它可以降低你從JSON中取出資料的程式碼的複雜度,同時降低了維護的成本。
要我說的話,它應該成為parse JSON的標配。具體來說,它是一種可以用來從JSON中取得指定結構的查詢語言,正如它官網自己所說的:
JMESPath is a query language for JSON.
案例-從ElasticSearch API取出結構化資料
比如說ElasticSearch的Date Histogram Aggregation API會回傳一個JSON:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"aggregations": { | |
"sales_over_time": { | |
"buckets": [ | |
{ | |
"key_as_string": "2015-01-01", | |
"key": 1420070400000, | |
"doc_count": 3 | |
}, | |
{ | |
"key_as_string": "2015-02-01", | |
"key": 1422748800000, | |
"doc_count": 2 | |
}, | |
{ | |
"key_as_string": "2015-03-01", | |
"key": 1425168000000, | |
"doc_count": 2 | |
} | |
] | |
} | |
} | |
} |
我想使用下面的PHP程式碼
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$buckets = $json['aggregations']['sales_over_time']['buckets']; | |
foreach ($buckets as $bucket) { | |
$result[] = [ | |
'key' => $bucket['key_as_string'], | |
'value' => $bucket['doc_count'] | |
]; | |
} |
把它轉成下列這個格式的陣列:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
[ | |
[ | |
'key' => '2015-01-01', | |
'value' => 3 | |
], | |
[ | |
'key' => '2015-02-01', | |
'value' => 2 | |
], | |
[ | |
'key' => '2015-03-01', | |
'value' => 2 | |
], | |
] |
有經驗的人應該很清楚, 當遇到複雜的JSON、而且要取出更多資料的時候, 上面這段程式碼的複雜度會急速飆高,而且難以維護。
如果使用JMESPath, 你可以透過下列的語法得到一樣的結果:
aggregations.sales_over_time.buckets[*].{key: key_as_string, value: doc_count}
在官網實驗JmesPath
如果你有興趣,可以到JMESPath官網,貼上更複雜的JSON,自己動手玩。比如說把上面這案例貼上去……