之前介绍过 JSONPath 的使用,但是它只能支持一些简单场景下快速从json中获取指定的值,这次我们来看一款更强大的工具 JSONata,它是一种针对 JSON 数据的轻量级查询和转换语言,可以实现一些比较复杂的逻辑,现在我们就来看一下如何进行使用
先以一段json作为基础数据,看一下可以支持进行的操作
1 | { |
查询
可以直接通过属性名获取对应的数据,或者根据条件过滤取数据(相比 JSONPath 不再需要前面的$
符号)
当前节点使用 $ , 上一级节点可以使用 %
JSONata | 结果 |
---|---|
FirstName | “Fred” |
Address.Street | “Hursley Park” |
Phone[0].number | “0203 544 1234” |
Phone[-1] | { “type”: “mobile”, “number”: “077 7700 1234” } |
Phone[type=’home’] | { “type”: “home”, “number”: “0203 544 1234” } |
Phone[type=’office’].number | [ “01962 001234”, “01962 001235” ] |
Phone[type=’office’].%.Age | [28, 28] – (%表示上一级) |
表达式
支持字符串的拼接,数值计算,计较等逻辑计算
JSONata | 结果 | 说明 |
---|---|---|
FirstName & ‘ ‘ & Surname | “Fred Smith” | 通过 & 连接字符串 |
Address.(Street & ‘, ‘ & City) | “Hursley Park, Winchester” | 通过括号可以连接不同属性值 |
5 & 0 & true | “50true” | 可以将其他类型转换为字符串 |
Age + 1 | 29 | 可以支持数值的加减乘除 |
Age > 20 | true | 可以进行比较逻辑运算 |
“01962 001234” in Phone.number | true | 判断集合是否包含元素 |
[1..5] | [1, 2, 3, 4, 5] | 获取范围区间 |
[1..5].($*$) | [1, 4, 9, 16, 25] | 获取范围区间并进行计算 |
Age < 50 ? “Young” : “Old” | “Young” |
结果结构转换
可以对结果进行结构的转换
JSONata | 结果 | 说明 |
---|---|---|
Email.address | [“fred.smith@my-work.com“,”fsmith@my-work.com“,”freddy@my-social.com“,”frederic.smith@very-serious.com“] | address为数组时,会自动打平 |
Email.[address] | [[“fred.smith@my-work.com“,”fsmith@my-work.com“],[“freddy@my-social.com“,”frederic.smith@very-serious.com“]] | 这种写法会将address以数组格式返回 |
[Address, Other.`Alternative.Address`].City | [“Winchester”,”London”] | 可以同时取多个对象的同一个属性 |
Phone.{type: number} | [{“home”:”0203 544 1234”},{“office”:”01962 001234”},{“office”:”01962 001235”},{“mobile”:”077 7700 1234”}] | 将Phone中的type作为key, number作为value转换成一个对象,最终放到一个集合中 |
Phone{type: number} | {“home”:”0203 544 1234”, “office”:[“01962 001234”,”01962 001235”],”mobile”:”077 7700 1234”} | 将Phone中的type作为key, number作为value转换成一个对象,重复的数据会转成一个集合,相当于groupby操作 |
Phone{type: number[]} | {“home”:[“0203 544 1234”],”office”:[“01962 001234”,”01962 001235”],”mobile”:[“077 7700 1234”]} | 将Phone中的type作为key, number作为value转换成一个对象,value强制使用集合类型 |
Phone{‘PhoneNumber’: number[]} | {“PhoneNumber”:[“0203 544 1234”,”01962 001234”,”01962 001235”,”077 7700 1234”]} | 转换时,key和value也可以使用普通的类型 |
Phone.(type & ‘: ‘ & number) | [“home: 0203 544 1234”,”office: 01962 001234”,”office: 01962 001235”,”mobile: 077 7700 1234”] | 可以通过括号对一个对象中的属性进行操作 |
分组与聚合
JSONata | 结果 | 说明 |
---|---|---|
Phone{type: {‘name’:type, ‘phone’: number}} | {“home”:{“name”:”home”,”phone”:”0203 544 1234”},”office”:{“name”:[“office”,”office”],”phone”:[“01962 001234”,”01962 001235”]},”mobile”:{“name”:”mobile”,”phone”:”077 7700 1234”}} | 按照type分组,之后针对每个组内的元素获取name和phone(多个) |
Phone{type: $} | {“home”:{“type”:”home”,”number”:”0203 544 1234”},”office”:[{“type”:”office”,”number”:”01962 001234”},{“type”:”office”,”number”:”01962 001235”}],”mobile”:{“type”:”mobile”,”number”:”077 7700 1234”}} | 将Phone按照type分组 |
Phone{type: $.{‘name’:type, ‘phone’: number}} | {“home”:{“name”:”home”,”phone”:”0203 544 1234”},”office”:[{“name”:”office”,”phone”:”01962 001234”},{“name”:”office”,”phone”:”01962 001235”}],”mobile”:{“name”:”mobile”,”phone”:”077 7700 1234”}} | 将Phone按照type分组后,针对每个value对象进行转换 |
Phone{type: $.(type & ‘: ‘ & number)} | {“home”:”home: 0203 544 1234”,”office”:[“office: 01962 001234”,”office: 01962 001235”],”mobile”:”mobile: 077 7700 1234”} | 按照type分组后,针对每组内的对象进行转换计算 |
函数支持
JSONata内置支持了许多函数,同时也支持自定义的函数,如使用自定义函数
1 | ( |
将输出结果:500
同时还支持函数的链式调用:value ~> $funcA ~> $funcB
,如
1 | ( |
输出结果:"SOME WORDS"
全部的内置函数如下,具体用法可以参考 http://docs.jsonata.org/overview
字符串函数
$string | $length | $substring | $substringBefore |
---|---|---|---|
$substringAfter | $uppercase | $lowercase | $trim |
$pad | $contains | $split | $join |
$match | $replace | $eval | $base64encode |
$base64decode | $encodeUrlComponent | $encodeUrl | $decodeUrlComponent |
$decodeUrl |
数值函数
$number | $floor | $abs | $ceil |
---|---|---|---|
$round | $power | $sqrt | $random |
$formatNumber | $formatBase | $formatInteger | $parseInteger |
聚合函数
$sum | $max | $min | $average |
---|
布尔函数
$boolean | $not | $exists |
---|
数组函数
$count | $append | $sort | $reverse |
---|---|---|---|
$shuffle | $distinct | $zip |
对象函数
$keys | $lookup | $spread | $merge |
---|---|---|---|
$sift | $each | $error | $assert |
$type |
时间函数
$now | $millis | $fromMillis | $toMillis |
---|
高阶函数
$map | $filter | $single | $reduce |
---|---|---|---|
$sift |
在Java项目中使用的话,可以使用JSONata4Java