当我尝试通过sbt package
创建以下软件包时:
import org.apache.spark.sql.SparkSession
class Log(val cip: String, val scstatus: Int) {
var src: String = cip
var status: Int = scstatus
}
object IISHttpLogs {
def main(args: Array[String]) {
val logFiles = "D:/temp/tests/wwwlogs"
val spark = SparkSession.builder.appName("LogParser").getOrCreate()
val sc = spark.sparkContext;
sc.setLogLevel("ERROR")
val logs = sc.textFile(logFiles)
import spark.implicits._
val rowDF = logs.filter(l => !l.startsWith("#"))
.map(l => l.split(" "))
.map(c => new Log(c(8), c(11).trim.toInt))
.toDF();
println(s"line count: ${rowDF.count()}")
rowDF.createOrReplaceTempView("rows")
val maxHit = spark.sql("SELECT top 1 src, count(*) FROM rows group by src order by count(*) desc")
maxHit.show()
spark.stop()
}
}
我收到以下错误:
value toDF不是org.apache.spark.rdd.RDD [Log]的成员
我尝试了几种方法:
imlicits._
我只是无法编译我的代码。
欢迎您使用ovverride这个错误。
我很好地读过Generate a Spark StructType / Schema from a case class并写道:
val schema =
StructType(
StructField("src", StringType, false) ::
StructField("status", IntegerType, true) :: Nil)
val rowRDD = logs.filter(l => !l.startsWith("#"))
.map(l => l.split(" "))
.map(c => Row(c(8), c(11).trim.toInt));
val rowDF = spark.sqlContext.createDataFrame(rowRDD, schema);
但是这样做,我不使用Log
类。我想知道是否存在通过使用定义的DataFrame
类来获取Log
的方法,或者官方/最佳方法是使用{{1} }类?
例如我不能写:
Row
我就是不知道为什么吗?
答案 0 :(得分:2)
您必须使用案例类。至少对我有用:
case class Log(cip: String, scstatus: Int)
//...
.map(c => Log(c(8), c(11).trim.toInt) // ommit 'new'
.toDF()
我不太确定这是否是一般规则。但是,在Dataset API的公告中,明确提到了案例类的用法:
Spark 1.6支持自动生成多种类型的编码器,包括原始类型(例如String,Integer,Long),Scala案例类和Java Bean。 (https://databricks.com/blog/2016/01/04/introducing-apache-spark-datasets.html)
如果您不能使用案例类,则this answer似乎是合适的。