hbase filter及rowkey范围检索使用并对结果集处理

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()

  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ink__Bamboo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值