Java 怎样解析和计算 json?

 

可以用一些类库解析json,比如sf.json\Gson\JsonPath等,但大多数没有进一步计算的能力,个别类库只能做最简单的条件查询,常见的计算几乎都要硬编码。内嵌数据库有较强的计算能力,但必须先经历繁琐的入库过程,适合时效性不敏感的情况,另外SQL是基于二维结构化数据的,并不是为多层JSON设计的,计算能力会大打折扣。

使用开源的集算器SPL能够更方便地解析jsonSPL专为多层结构而设计,可以大幅简化json的计算,SPL函数丰富语法灵活,具有强大的计算能力。

SPL提供了方便调用的JDBC接口,初学者也可以轻松入门。比如,某json文件有两层,上层是员工记录,每条员工记录的Orders字段是订单记录的集合,将该文件解析为序表(SPL的多层数据对象):


Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();
String str="=json(file("d:/data.json").read())";
ResultSet result = statement.executeQuery(str);

可以看到,SPL无需入库,可以直接解析JSON文件SPL还可以直接读取并解析restful,代码同样简单:
=json(httpfile("http://127.0.0.1:6868/api/getData").read())

SPL也可以直接读取并解析来自特殊数据源的json,比如MongoDBelsticSearch

SPL序表可以轻松计算多层JSON,代码简单易懂比如,对所有员工的所有订单进行条件查询,找到金额属于某区间,且客户名称包含某字符串的订单。SPL代码如下:
=json(file("d:/data.json").read()).conj(Orders).select((Amount>1000 && Amount<=2000) && like@c(Client,"*business*"))

SPL支持算法外置,适合代码较长或频繁修改的计算,可显著降低耦合性。比如上面的条件查询可以先存为脚本文件:


A

B

1

=json(file("d:\\data.json").read())

/多层json

2

=A1.conj(Orders)

/合并订单

3

=A2.select((Amount>1000 &&   Amount<=2000) && like@c(Client,"*business*"))

/条件查询

再在JDBC中以存储过程的形式调用脚本文件:


Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery("call getQuery()");
...

SPL内置丰富的库函数,提供了等价于SQL的计算能力,下面试举几例:


A


2

….


3

=A2.conj(Orders).groups(Client;sum(Amount))

分组汇总

4

=A2.groups(State,Gender;avg(Salary),count(1))

多字段分组汇总

5

=A2.sort(Salary)

排序

6

=A2.id(State)

去重

7

=A2.new(Name,Gender,Dept,Orders.OrderID,Orders.Client,Orders.Client,Orders.SellerId,Orders.Amount,Orders.OrderDate)

关联

有些运算逻辑比较复杂,用SQL或存储过程也很难实现,而SPL具有丰富的函数和灵活的语法,可以大幅简化复杂运算逻辑。比如:json文件存储了客户名单及其销售额,要找出销售额累计占到一半的前n个大客户,并按销售额从大到小排序。


A

B

1

=json(file("d:\\sales.json").read()).sort(amount:-1)

 取数并逆序排序

2

=A1.cumulate(amount)

计算累计序列

3

=A2.m(-1)/2

最后的累计值即是总和

4

=A2.pselect(~>=A3)

超过一半的位置

5

=A1(to(A4))

按位置取值

SPL提供了专业的IDE,不仅有完整的调试,还能用表格的形式观察每一步的中间计算结果,特别适合设计复杂的运算逻辑:

IDEpng

SPL序表可以直接表达多层json,而无需像SQL那样用二维记录做中间过度,特别适合简化多层json的计算。比如:json文件有多层子文档和多层集合(数组),部分数据如下:

[
     {
        "race": {
              "raceId":"1.33.1141109.2",
              "meetingId":"1.33.1141109"
        },
        ...
        "numberOfRunners": 2,
        "runners": [
          {       "horseId":"1.00387464",
                  "trainer": {
                      "trainerId":"1.00034060"
                  },
              "ownerColours":"Maroon,pink,dark blue."
            },
            {     "horseId":"1.00373620",
                  "trainer": {
                      "trainerId":"1.00010997"
                  },
              "ownerColours":"Black,Maroon,green,pink."
            }
        ]
     },
  ...
  ]

trainerId分组,统计每组中ownerColours的成员个数,只需如下代码:


A

1

=json(file("/workspace/JSONstr.json").read())

2

=A1(1).runners

3

=A2.groups(trainer.trainerId;   ownerColours.array().count():times)

SPL结构轻便、入门成本低、解析方便、数据源种类多、计算能力强。使用SPL后,可以方便地在Java中实现多层json的计算以及逻辑复杂的计算。