如何将splited String映射到一个类?

时间:2017-04-25 13:30:31

标签: scala apache-spark

我从HDFS加载了一个表,并且该表实际上有300列。但是我加载的是一个具有一个列名称值的表,并且每一行的列的原始值在这一个colunm中一起分割为" /吨"

像这样

+——————————+
|               value|
+--------------------+
|1489763115 SS EN-...|
|1489763140 SS EN-...|
|1489763552 SS EN-...|
|1489763552 PE EN-...|
|1489763553 PE EN-...|
|1489763554 PE EN-...|
|1489763585 SS EN-...|

我需要做的是将每行的长字符串从一个colunms拆分为300列,并将其设为Json。 所以我尝试将数据集(RDD String)转换为数组,并将每一行映射到类。并将新数据集转换为String。

有我的代码:

//this is the class I want to map to 

case class MapThing(gmt:Int,Name:String,Language:String,.....500 of them)


//data is the RDD[String] I get from the HDFS

val packagesRDD = data
val packagesDF = data.toDF
packagesDF.show(false)
/*

+——————————+
|               value|
+--------------------+
|1489763115 SS EN-...|
|1489763140 SS EN-...|
|1489763552 SS EN-...|
|1489763552 PE EN-...|
|1489763553 PE EN-...|
|1489763554 PE EN-...|
|1489763585 SS EN-...|

*/

//here to process the data:
    data.map(line => {
      var arr = line.split("/t",-1)
      OmnitureHitHourly(arr(0).toInt,arr(1),arr(2),arr(3),arr(4).,arr(5)....arr(299))
}).toJSON

但IDE无法识别分割。

我也尝试:

val array = packagesDF.collect()
packagesDF.collect()
.foreach(row => {row.get(0).toString
.map(line=>{
val arr = line.split("/t",-1)

OmnitureHitHourly(arr(0).toInt,arr(1),arr(2),arr(3),arr(4)。,arr(5).... arr(299))}      )})      .toJSON

它抛出了一个stackoverflow异常..

=============================================== ===============================

现在是我写的,

 case class ThingNeedMap(
                                  gmt : String,//Int
                                  name : String,//BigInt
                                  language : String,//BigInt
                                  date_time : String,
                              ...500 fielsd

                                )


    val sqlContext = new SQLContext(sc)
    import sqlContext.implicits._

    println("Data: ", data)
    val packagesRDD = data
//    val packagesDF = data.toDF
    val packagesDF = data.toDF
    data.map(line => {
      val arr = line.split("/t",-1)
      ThingNeedMap(arr(0),arr(1),arr(2),arr(3),arr(4),arr(5),arr(6),arr(7),arr(8),arr(9),arr(10),
        arr(11),arr(12),arr(13),arr(14),arr(15),arr(16),arr(17),arr(18),arr(19),arr(20),
        arr(21),arr(22),arr(23),arr(24),arr(25),arr(26),arr(27),arr(28),arr(29),arr(30),
        arr(31),arr(32),arr(33),arr(34),arr(35),arr(36),arr(37),arr(38),arr(39),arr(40),
        arr(41),arr(42),arr(43),arr(44),arr(45),arr(46),arr(47),arr(48),arr(49),arr(50),
        arr(51),arr(52),arr(53),arr(54),arr(55),arr(56),arr(57),arr(58),arr(59),arr(60),
        arr(61),arr(62),arr(63),arr(64),arr(65),arr(66),arr(67),arr(68),arr(69),arr(70),
        arr(71),arr(72),arr(73),arr(74),arr(75),arr(76),arr(77),arr(78),arr(79),arr(80),
        arr(81),arr(82),arr(83),arr(84),arr(85),arr(86),arr(87),arr(88),arr(89),arr(90),
        arr(91),arr(92),arr(93),arr(94),arr(95),arr(96),arr(97),arr(98),arr(99),arr(100),
        arr(101),arr(102),arr(103),arr(104),arr(105),arr(106),arr(107),arr(108),arr(109),arr(110),
        arr(111),arr(112),arr(113),arr(114),arr(115),arr(116),arr(117),arr(118),arr(119),arr(120),
        arr(121),arr(122),arr(123),arr(124),arr(125),arr(126),arr(127),arr(128),arr(129),arr(130),
        arr(131),arr(132),arr(133),arr(134),arr(135),arr(136),arr(137),arr(138),arr(139),arr(140),
        arr(141),arr(142),arr(143),arr(144),arr(145),arr(146),arr(147),arr(148),arr(149),arr(150),
        arr(151),arr(152),arr(153),arr(154),arr(155),arr(156),arr(157),arr(158),arr(159),arr(160),
        arr(161),arr(162),arr(163),arr(164),arr(165),arr(166),arr(167),arr(168),arr(169),arr(170),
        arr(171),arr(172),arr(173),arr(174),arr(175),arr(176),arr(177),arr(178),arr(179),arr(180),
        arr(181),arr(182),arr(183),arr(184),arr(185),arr(186),arr(187),arr(188),arr(189),arr(190),
        arr(191),arr(192),arr(193),arr(194),arr(195),arr(196),arr(197),arr(198),arr(199),arr(200),
        arr(201),arr(202),arr(203),arr(204),arr(205),arr(206),arr(207),arr(208),arr(209),arr(210),
        arr(211),arr(212),arr(213),arr(214),arr(215),arr(216),arr(217),arr(218),arr(219),arr(220),
        arr(221),arr(222),arr(223),arr(224),arr(225),arr(226),arr(227),arr(228),arr(229),arr(230),
        arr(231),arr(232),arr(233),arr(234),arr(235),arr(236),arr(237),arr(238),arr(239),arr(240),
        arr(241),arr(242),arr(243),arr(244),arr(245),arr(246),arr(247),arr(248),arr(249),arr(250),
        arr(251),arr(252),arr(253),arr(254),arr(255),arr(256),arr(257),arr(258),arr(259),arr(260),
        arr(261),arr(262),arr(263),arr(264),arr(265),arr(266),arr(267),arr(268),arr(269),arr(270),
        arr(271),arr(272),arr(273),arr(274),arr(275),arr(276),arr(277),arr(728),arr(279),arr(280),
        arr(281),arr(282),arr(283),arr(284),arr(285),arr(286),arr(287),arr(288),arr(289),arr(290),
        arr(291),arr(292),arr(293),arr(294),arr(295),arr(296),arr(297),arr(298),arr(299),arr(300),
        arr(301),arr(302),arr(303),arr(304),arr(305),arr(306),arr(307),arr(308),arr(309),arr(310),
        arr(311),arr(312),arr(313),arr(314),arr(315),arr(316),arr(317),arr(318),arr(319),arr(320),
        arr(321),arr(322),arr(323),arr(324),arr(325),arr(326),arr(327),arr(328),arr(329),arr(330),
        arr(331),arr(332),arr(333),arr(334),arr(335),arr(336),arr(337),arr(338),arr(339),arr(340),
        arr(341),arr(342),arr(343),arr(344),arr(345),arr(346),arr(347),arr(348),arr(349),arr(350),
        arr(351),arr(352),arr(353),arr(354),arr(355),arr(356),arr(357),arr(358),arr(359),arr(360),
        arr(361),arr(362),arr(363),arr(364),arr(365),arr(366),arr(367),arr(368),arr(369),arr(370),
        arr(371),arr(372),arr(373),arr(374),arr(375),arr(376),arr(377),arr(378),arr(379),arr(380),
        arr(381),arr(382),arr(383),arr(384),arr(385),arr(386),arr(387),arr(388),arr(389),arr(390),
        arr(391),arr(392),arr(393),arr(394),arr(395),arr(396),arr(397),arr(398),arr(399),arr(400),
        arr(401),arr(402),arr(403),arr(404),arr(405),arr(406),arr(407),arr(408),arr(409),arr(410),
        arr(411),arr(412),arr(413),arr(414),arr(415),arr(416),arr(417),arr(418),arr(419),arr(420),
        arr(421),arr(422),arr(423),arr(424),arr(425))

    }).toJSON

并抛出异常..

Error:scalac: Error: org.jetbrains.jps.incremental.scala.remote.ServerException
java.lang.StackOverflowError    at scala.reflect.internal.util.Collections$class.mapList(Collections.scala:52)

还有其他更好的方法来逃避映射步骤吗?我只想要一个带有键和值的json ..而且键是旧表中的列,而不是只有一列的列。

1 个答案:

答案 0 :(得分:1)

没有理智的程序有300或500或任何字段的类。所以编译器没有经过测试,其内部方法和数据结构也被破坏了。解决这个问题需要付出巨大的努力,原因很简单(除非希望改进能够过滤到理智的程序,但是直接改进它们的性能需要明显优先)。您可以尝试购买一台超级计算机来编译您的程序(不要)。

Spark可能不会在数据帧方面遇到类似的问题,但我不确定。但是你也没有必要:只需使用杰克逊直接将你的RDD[String]映射到你想要的JSON,Spark本身使用它:

import org.apache.spark.sql.types.DataTypes._
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.JsonNodeFactory

val fields = sc.broadcast(Array(("gmt", IntegerType), ("name", StringType), ...))

data.map { line =>
  val arr = line.split("\t", -1)
  val jsonObjectNode = JsonNodeFactory.instance.objectNode()
  for { ((fieldName, fieldType), value) <- fields.value.zip(arr) }
    fieldType match {
      case IntegerType =>
        jsonObjectNode.put(fieldName, value.toInt)
      case DoubleType =>
        jsonObjectNode.put(fieldName, value.toDouble)
      ...
    }
    (new ObjectMapper).writeValueAsString(jsonObjectNode)
}

或类似的东西。 我已经检查过,编译器似乎正好处理了数百个vararg参数,但如果遇到问题,只需从文件中加载它们或连接几个数组。