在Argonaut中解析子文档

时间:2017-04-05 12:02:37

标签: scala parsing argonaut

我正在尝试使用Argonaut scala库解析Json:

{"took":5,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hit
s":{"total":1285,"max_score":0.99627554,"hits":[{"_index":"logstash-2017.03.15",...

Parse.parseWith(posts, .field(“take”)。flatMap( .string).getOrElse(“42”),msg => msg)工作正常得到“拿走了“田野。

现在,我无法想出一种方法来访问嵌套值,例如hits-> total。 另一个问题,虽然我们的目标是如何通过索引访问列表元素,如命中 - >点击次数 - >元素0 - > _index在我的情况下得到logstash-2017.03.15。

1 个答案:

答案 0 :(得分:1)

要从嵌套对象中获取信息,您必须深入了解传递的函数(功能方式)。 我的意思是.map( .getField()。map( .getField()。map)) - 你在这个领域内越走越深。

您还会注意到toInt类型返回一个选项,因此我们使用的是flatMap

import argonaut._, Argonaut._

val posts: String = """{
                     |   "took":5,
                     |   "timed_out":false,
                     |   "_shards":{
                     |      "total":5,
                     |      "successful":5,
                     |      "failed":0
                     |   },
                     |   "hits":{
                     |      "total":1285,
                     |      "max_score":0.99627554,
                     |      "hits":[
                     |         {
                     |            "_index":"logstash-2017.03.15"
                     |         }
                     |      ]
                     |   }
                     |}""".stripMargin


val took = Parse.parseWith(posts, _.field("took").flatMap(_.number.flatMap(_.toInt)).getOrElse(0), msg => 0)

val hitsTotal = Parse.parseWith(posts, _.field("hits").flatMap(
                                          _.field("total").flatMap(_.number.flatMap(_.toInt))
                                       ).getOrElse(0), msg => 0)

val hitsList = Parse.parseWith[List[Json]](posts, _.field("hits").flatMap(_.field("hits").flatMap(_.array)).getOrElse(List()), msg => List())

结果:

took: Int = 5
hitsTotal: Int = 1285
hitsList: List[argonaut.Json] = List({"_index":"logstash-2017.03.15"})

您会注意到hitsList只是一个包含更多JSON的普通列表,您可以使用.field()