hbase新API操作hbase过滤器之后对结果集进行处理生成spark临时表用于后续处理。
注意hbase中,表中存储的数据类型必须一一对应,否则会因为解码问题,导致最后结果非常的混乱
代码如下: (如有大神看到,请不吝赐教,交流邮箱1970497138@qq.com)
val show_info_one:Array[(String,String,String)] = Array(
//查找需要使用的列 填充此处
("cf","user_id","Long"),
.........
)
//注册成的表名:ywapp_bigdata_user_score_tmp
FilterRowkeyGetHtable(sp,"db_oss_ywgl:ywapp_bigdata_user_score",show_info_one,getDateTime(0))
sp.sql("select * from ywapp_bigdata_user_score_tmp limit 10").show()
sp.sql("select count(1) from ywapp_bigdata_user_score_tmp").show()
val show_info_two:Array[(String,String,String)] = Array(
//查找需要使用的列 填充此处
("cf","user_id","Long"),
.........
)
//注册成的表名:ywapp_bigdata_user_indicator_tmp
FilterRowkeyGetHtable(sp,"db_oss_ywgl:ywapp_bigdata_user_indicator",show_info_two,getDateTime(0))
sp.sql("select * from ywapp_bigdata_user_indicator_tmp limit 10").show()
sp.sql("select count(1) from ywapp_bigdata_user_indicator_tmp").show()
/**
* 根据rowkey进行数据筛选
* 测试:使用scan的setStartRow设置rowkey的起始位置,
* 可以指定rowkey的前缀进行匹配查询,
* 不可以指定rowkey中间的一部分进行数据筛选
* @param sparkSesson
* @param tbl_nm 表名
* @param show_info 展示的列名(cf,col_nm,valueType)
* @param tuple rowkey对日期筛选的条件,startTime,endTime 区间是[startTime,endTime)
* @param filters 过滤器元素(cf,col_nm,filterValue),默认为空
* 注册成临时表:tabl_nm_tmp
*/
private def FilterRowkeyGetHtable(sparkSesson:SparkSession,tbl_nm:String,show_info:Array[(String,String,String)],tuple:Tuple2[String,String],filters:Array[(String,String,String)]=Array(("","",""))): Unit ={
val sparkContext = sparkSesson.sparkContext
val sqlContext = sparkSesson.sqlContext
val hbaseconf = HBaseConfiguration.create()
hbaseconf.set(TableInputFormat.INPUT_TABLE,tbl_nm)
val table = new HTable(hbaseconf,tbl_nm)
val scan = new Scan()
scan.setStartRow(Bytes.toBytes(tuple._1))
scan.setStopRow(Bytes.toBytes(tuple._2))
//添加自定义过滤器
if(filters.length>0){
for(filter<-filters){
val f = new SingleColumnValueFilter(Bytes.toBytes(filter._1),Bytes.toBytes(filter._2),CompareFilter.CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes( filter._3)))
scan.setFilter(f)
}
}
for(i <- show_info){
scan.addColumn(Bytes.toBytes(i._1),Bytes.toBytes(i._2))
}
val ScannerRes = table.getScanner(scan)
val ColumnValueScanner = ScannerRes.iterator()
/**
* -------------------------重点-----------------------------
* 将扫描得到的结果值转换成可以匹配注册表用的RDD[ROW]
* 使用
*
* 此处对ColumnValueScanner的处理不完善,需要后续修改,查找有效的方法
*/
val listRow = new util.ArrayList[Row]()
var flag = true
while(ColumnValueScanner.hasNext){
try{
//每个result都是一行数据
val r:Result = ColumnValueScanner.next()
val arr = ArrayBuffer[Any]()
//正常此处需要根据structType中元素类型,以及表中元素的类型指定类型,但是此处由于部分未知原因,转换为其他类型会报错,故统一转换成String
//获取rowkey
arr+=Bytes.toString(r.getRow)
//*************---------------------------此处需要指定每列的类型进行模式匹配处理
for(col<-show_info){
col._3 match {
case "Float"=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes()) //此部分由于类型转换内部存在调用bytes.length操作,需要对空指针数据进行处理
if(v!=null)arr+=Bytes.toFloat(v) else arr+=v
}
case "Int"=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes())
if(v!=null)arr+=Bytes.toInt(v) else arr+=v
}
case "Double"=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes())
if(v!=null)arr+=Bytes.toDouble(v) else arr+=v
}
case "Long"=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes())
if(v!=null)arr+=Bytes.toLong(v) else arr+=v
}
case "String"=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes())
if(v!=null)arr+=Bytes.toString(v) else arr+=v
}
case _=>{
val v = r.getValue(col._1.getBytes(),col._2.getBytes())
if(v!=null)arr+=Bytes.toString(v) else arr+=v
}
}
}
val row = Row.fromSeq(arr.toSeq)
listRow.add(row)
}catch{
case e:Exception=> e.printStackTrace()
}
}
//构建RDD
//val seqRDD = sc.makeRDD(arr)
val schema = StructType({
val list = new util.ArrayList[StructField]()
list.add(StructField("rowkey",StringType,true))
for(col<-show_info){
col._3 match{
case "Float"=>list.add( StructField(col._2,FloatType,true))
case "Int"=>list.add( StructField(col._2,IntegerType,true))
case "Double"=>list.add( StructField(col._2,DoubleType,true))
case "Long"=>list.add( StructField(col._2,LongType,true))
case "String"=>list.add( StructField(col._2,StringType,true))
case _=>list.add( StructField(col._2,StringType,true))
}
}
list
}
)
//创建dataframe
val df = sqlContext.createDataFrame(listRow,schema)
val tbl = tbl_nm.split(":")(1)
df.createTempView(tbl+"_tmp")
// println("----------------------------------"+sqlContext.sql(s"select * from $tbl"+"_tmp").count())
ScannerRes.close()
}