【问题标题】:Convert RDD to JSON Object将 RDD 转换为 JSON 对象
【发布时间】:2015-08-25 19:25:43
【问题描述】:

我有一个 RDD[(String, List[String])] 类型的 RDD。

例子:

(FRUIT, List(Apple,Banana,Mango))
(VEGETABLE, List(Potato,Tomato))

我想将上面的输出转换为如下的 json 对象。

{
  "categories": [
    {
      "name": "FRUIT",
      "nodes": [
        {
          "name": "Apple",
          "isInTopList": false
        },
        {
          "name": "Banana",
          "isInTopList": false
        },
        {
          "name": "Mango",
          "isInTopList": false
        }
      ]
    },
    {
      "name": "VEGETABLE",
      "nodes": [
        {
          "name": "POTATO",
          "isInTopList": false
        },
        {
          "name": "TOMATO",
          "isInTopList": false
        },
      ]
    }
  ]
}

请建议最好的方法。

注意:"isInTopList": false 始终保持不变,并且必须与 jsonobject 中的每个项目一起存在。

【问题讨论】:

  • 使用任何图书馆,例如 Play、Lift 或 Jakson
  • 如果输入中没有换行等风险,使用简单的字符串替换创建输出可能会更快。如果您无法对输入做出假设,请使用库。
  • 在本地运行时,你可以创建任何你想要的东西,但是当你在实际集群中运行时,对所需位置的写入操作只能通过Spark函数进行,并且Spark不允许直接保存到JSON

标签: json scala apache-spark


【解决方案1】:

首先我用下面的代码重现了你提到的场景:

val sampleArray = Array(
("FRUIT", List("Apple", "Banana", "Mango")),
("VEGETABLE", List("Potato", "Tomato")))

val sampleRdd = sc.parallelize(sampleArray)
sampleRdd.foreach(println) // Printing the result

现在,我正在使用json4s Scala 库将此 RDD 转换为您请求的 JSON 结构:

import org.json4s.native.JsonMethods._
import org.json4s.JsonDSL.WithDouble._

val json = "categories" -> sampleRdd.collect().toList.map{
case (name, nodes) =>
  ("name", name) ~
  ("nodes", nodes.map{
    name => ("name", name)
  })
}

println(compact(render(json))) // Printing the rendered JSON

结果是:

{"categories":[{"name":"FRUIT","nodes":[{"name":"Apple"},{"name":"Banana"},{"name":"Mango"}]},{"name":"VEGETABLE","nodes":[{"name":"Potato"},{"name":"Tomato"}]}]}

【讨论】:

    【解决方案2】:

    由于您希望为整个 RDD 提供一个 JSON,因此我将从 Rdd.collect 开始。请注意您的集合适合内存,因为这会将数据移回驱动程序。

    要获取 json,只需使用库来遍历您的对象。我喜欢 Json4s,因为它内部结构简单,操作符实用、干净。这是他们网站上的一个示例,展示了如何遍历嵌套结构(特别是列表):

    object JsonExample extends App {
      import org.json4s._
      import org.json4s.JsonDSL._
      import org.json4s.jackson.JsonMethods._
    
      case class Winner(id: Long, numbers: List[Int])
      case class Lotto(id: Long, winningNumbers: List[Int], winners: List[Winner], drawDate: Option[java.util.Date])
    
      val winners = List(Winner(23, List(2, 45, 34, 23, 3, 5)), Winner(54, List(52, 3, 12, 11, 18, 22)))
      val lotto = Lotto(5, List(2, 45, 34, 23, 7, 5, 3), winners, None)
    
      val json =
        ("lotto" ->
          ("lotto-id" -> lotto.id) ~
          ("winning-numbers" -> lotto.winningNumbers) ~
          ("draw-date" -> lotto.drawDate.map(_.toString)) ~
          ("winners" ->
            lotto.winners.map { w =>
              (("winner-id" -> w.id) ~
               ("numbers" -> w.numbers))}))
    
      println(compact(render(json)))
    }
    

    【讨论】:

    • 你好丹尼尔,我可以在数据框中迭代这个方法来将我的数据转换成一个 json 对象吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多