hbase通过行键查询多VERSIONS数据

 一段非常长的数据,第一个是加密后的用户信息,后面依次是开始时间,结束时间,区县编码,经度,纬度....

现在我希望创建一张表,导入这些数据,查询一个用户最新的三次地点经纬度

我们就筛选一下数据,传入第一个,第二个,第四个,第五个就行

我将每个步骤分开了,下面的测试模块都是在第一个代码中的

一、创建连接

1、创建一个配置文件, 需要输入zookeeper节点信息,以及你的三台主机名称

2、创建连接

3、如果需要对表结构操作 则getAdmin;对数据进行操作,则getTable

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class HbaseDianXin {
    //设置全局变量方便下面的模块使用
    Connection conn;
    Admin admin;
    //获取连接
    @Before
    public void conn() throws IOException {
        //创建配置文件对象
        Configuration conf = HBaseConfiguration.create();
        //设置配置文件内容,zookeeper上的三个节点,通过zookeeper可以找到hbase
        conf.set("hbase.zookeeper.quorum","master:2181,node1:2181,node2:2181");
        conn = ConnectionFactory.createConnection(conf);
        admin = conn.getAdmin();
    }  
  
}

二、判断我们将要创建的表是否存在,存在就删除

应该注意的就是创建的是TableName对象,不是Table对象 

  @Test
    //如果存在这个表就删除
    public void delTable() throws IOException {
        //tableExists()这个方法里面需要的参数是TableName类型的数据,
        //conn.getTable(TableName.valueOf(""))这个方法获得的是Table类型的数据,不要混淆
        TableName dianxin = TableName.valueOf("dianxin");
        if(admin.tableExists(dianxin)){
            //表如果存在,就先disable,再delete
            admin.disableTable(dianxin);
            admin.deleteTable(dianxin);
        }else
            System.out.println("表不存在");
    }

三、创建表

1.创建一张表,并指定一个列簇 

2.对列簇可以追加配置, 我这里设置了最大versions为5,也就是保存了最新的5次插入的数据

3.创建表

//根据数据创建表
    @Test
    public void createTable() throws IOException {
        //首先我们获取这个表的结构
        HTableDescriptor dianxin = new HTableDescriptor(TableName.valueOf("dianxin"));
       //创建列簇
        HColumnDescriptor info = new HColumnDescriptor("info");
        //将列簇版本设置为5
        info.setMaxVersions(5);
        //向表中添加列簇
        dianxin.addFamily(info);

        admin.createTable(dianxin);
    }

四、插入数据

1.通过IO流读取文本数据

2.创建一个表的对象

3. 采用批量插入的方式,,创建一个集合存储put对象,设置一个批大小batchSize,先将每次读取的数据存储到一个put对象,再将这个put对象传入到创建的集合中

4.如果集合的大小到达了批设置的大小,就将他put进表中,

5.最后一次插入的数据有可能达不到设置的批大小,我们直接将他put进table中

 //插入数据
    @Test
    public void putAll() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("data/DIANXIN.csv"));
        Table dianxin = conn.getTable(TableName.valueOf("dianxin"));
        int batchSize=1000;
        String line=null;
        //创建集合存储put对象
        ArrayList<Put> puts = new ArrayList<Put>();
        while((line=br.readLine())!=null){
            String[] split = line.split(",");
            String mdn = split[0];
            String strat_time = split[1];
            String lg = split[4];
            String lat=split[5];
            Put put = new Put(mdn.getBytes());
            put.addColumn("info".getBytes(),"lg".getBytes(),Long.parseLong(strat_time),lg.getBytes());
            put.addColumn("info".getBytes(),"lat".getBytes(),Long.parseLong(strat_time),lat.getBytes());
            puts.add(put);
            if(puts.size()==batchSize){
                dianxin.put(puts);
                puts.clear();
            }
        }
        if(!puts.isEmpty()){
            dianxin.put(puts);
        }
    }

插入完数据后可以检查一下有多少行数据

在默认情况下,count是按1000行汇报一次,每次只会数1条

我们可以 count '表名',{INTERVAL=>10000,CACHE=>1000}

10000条汇报一次,每次数1000条数据

 

五、根据行键,查询最新的3次用户位置信息

1.获取到这张表

2.通过行键,想要获取的数据版本,确定我们将获取的数据内容

3.get方法获取这条数据,这条数据,里面包含了多个cell

4.创建2个集合分别用来接受经度和纬度,这里是为了最终结果好看做的

不用集合,用Bytes.toString(CellUtil.cloneValue(cell))输出也是正确结果,就是结构有点问题不好看

  @Test
    /**
     * 根据mdn,获取最新的3个记录
     */
    public void getPositionByMDN() throws IOException {
        Table dianxin = conn.getTable(TableName.valueOf("dianxin"));
        String mdn = "3FFB277F72B22C5F2A87F5C5934384AEB3B62C7C";
        //我们使用get方法,需要传入一个Get类型的对象
        //创建对象时需要传入行键
        Get get = new Get(mdn.getBytes());
        //设置我们获取的是3个版本
        get.setMaxVersions(3);
        Result result = dianxin.get(get);
        // 通过getValue这种方式只能获取到最新的记录
        // String lg = Bytes.toString(rs.getValue("info".getBytes(), "lg".getBytes()));
        // String lat = Bytes.toString(rs.getValue("info".getBytes(), "lat".getBytes()));
        // System.out.println(lg + "," + lat);
        List<Cell> cells = result.listCells();
        //创建集合分别用来接收经纬度
        ArrayList<String> lglist = new ArrayList<String>();
        ArrayList<String> latlist = new ArrayList<String>();
        for (Cell cell : cells) {
            String value = Bytes.toString(CellUtil.cloneValue(cell));
            String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
            if("lg".equals(qualifier)){
                lglist.add(value);
            }else if(("lat").equals(qualifier)){
                latlist.add(value);
            }
        }
        for (int i = 0; i < 3; i++) {
            System.out.println(lglist.get(i)+","+latlist.get(i));
        }
    }

### 回答1: HBase Shell是HBase提供的命令工具,可以通过它来查询数据。以下是一些常用的查询命令: 1. 查询表中所有数据:scan 'table_name' 2. 查询表中指定数据:get 'table_name', 'row_key' 3. 查询表中指定列族的数据:scan 'table_name', {COLUMN => 'column_family'} 4. 查询表中指定列族和列的数据:scan 'table_name', {COLUMNS => ['column_family:column_name']} 5. 查询表中指定、列族和列的数据:get 'table_name', 'row_key', {COLUMN => 'column_family:column_name'} 6. 查询表中指定的所有版本数据:get 'table_name', 'row_key', {VERSIONS => n} 其中,table_name为表名,row_key为,column_family为列族名,column_name为列名,n为版本数。 以上是HBase Shell查询数据的基本命令,可以根据实际需求进组合使用。 ### 回答2: HBase Shell是HBase的命令接口,用户可以使用它来查询、插入、更新和删除HBase中的数据HBase Shell是基于JRuby开发的,因此它支持Ruby语言的所有功能,例如变量、条件语句、循环等。 要在HBase Shell中查询数据,可以使用下列命令: 1. scan:扫描表中的所有数据。 语法:scan 'tablename' 示例:scan 'students' 结果:会输出students表中的所有数据。 2. get:通过指定来获取某一数据。 语法:get 'tablename', 'rowkey' 示例:get 'students', '001' 结果:会输出表students中为“001”的一数据。 3. count:统计表中的数量。 语法:count 'tablename' 示例:count 'students' 结果:会输出students表中的数量。 4. exists:判断表是否存在。 语法:exists 'tablename' 示例:exists 'students' 结果:如果 students 表存在,则会返回 "true",否则会返回 "false"。 5. describe:显示表的详细信息。 语法:describe 'tablename' 示例:describe 'students' 结果:会输出students表的详细信息,包括列族、等。 除此之外,还有许其他命令,例如filter、delete、put等,用户可以根据自己的需求进使用。需要注意的是,在HBase Shell中进数据查询时,可以使用种过滤器来筛选数据,这些过滤器包括列族过滤器、列名过滤器、值过滤器、时间戳过滤器等。使用过滤器能够很大程度上提高查询效率和精确度,用户可以根据自己的需求进选择。 ### 回答3: HBase是一种分布式开源NoSQL数据库,最常见的使用方法是使用HBase Shell来查询数据HBase Shell使用类似于命令的交互方式,允许用户在HBase数据库上执各种操作。以下是HBase Shell查询数据的示例。 1. 启动HBase Shell并连接到集群 在终端窗口中输入“hbase shell”即可启动HBase Shell。要连接到HBase集群,请输入“connect 'hostname'”,其中“hostname”是HBase集群的主机名或IP地址。 2. 选择要查询数据的表 在HBase Shell中,我们可以使用“list”命令列出集群中的所有表。要查询数据,请选择并进入目标表,可以使用“scan”命令查看表中的所有和列族。 3. 查询具体数据查询特定的数据,可以使用“get”命令。下面是一个示例查询: get 'table_name', 'rowkey', 'column_family:column_name' 其中,'table_name'是要查询的表的名称,'rowkey'是的唯一标识符,'column_family'和'column_name'分别是列族和列的名称。 4. 查询个具体数据 如果要查询数据,可以使用“get”命令的批量版本“getall”命令。下面是一个示例查询: getall 'table_name', ['rowkey1', 'rowkey2', 'rowkey3'], {COLUMN => ['column_family:column_name1', 'column_family:column_name2']} 该命令将返回包含数据的结果集。 5. 使用过滤器查询数据 HBase Shell提供了一些内置过滤器,可以按列族和列名等条件过滤查询结果。以下是一个示例: scan 'table_name', {FILTER => "ColumnPrefixFilter('prefix')"} 该命令将返回所有以“prefix”为前缀的列的值。 6. 嵌套查询数据 有时,我们需要嵌套查询数据,例如查询特定的所有子列。HBase Shell提供了“scan”和“get”命令的种选项,可以满足这种需求。 以上是HBase Shell查询数据的基本介绍。除了上述命令外,还有许其他选项可供选择,可以根据实际需要进设置和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值