目录
HBase 是一个分布式的、面向列的开源的 NoSQL 数据库。如果需要操作 HBase 通常有如下几种客户端可以使用:
- hbase-client:比较底层,需要自己进一步封装 api,而且版本号和安装的 hbase 也要匹配,否则会报错
- spring-data-hadoop:2019 年 4 月 5 停止维护
- Apache Phoenix:使用 SQL 的方式来操作 HBase。Phoenix 的性能很高(进行简单查询,其性能量级是毫秒),相对于 hbase 原生的 scan 并不会差多少,而对于类似的组件 hive、Impala 等,性能有着显著的提升
本文演示如何使用 hbase-client 操作 HBase 数据库。
1、Maven依赖
hbase-client 的Maven依赖:
<
dependency
>
<
groupId
>org.apache.hbase</
groupId
>
<
artifactId
>hbase-client</
artifactId
>
<
version
>2.3.0</
version
>
</
dependency
>
2、相关配置
#hbase config hbase.addresses=ip1,ip2,ip3 #hbase.addresses=hadoop hbase.port=2181 hbase.zookeeper.parent=/hbase hadoop.home.dir=E:/hadoop-common-2.2.0-bin-master
3、编写工具类
3.1、获取 hbase 参数
编写HBaseConfigInit.java来读取hbase 的配置,获取 hbase 参数:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* @author summer.lin
* @date 2023-03-23 14:34
*/
public class HBaseConfigInit {
public static final Logger LOGGER = LoggerFactory.getLogger(HBaseConfigInit.class);
private String quorum = new String();
private Integer port = 0;
private String parent = new String();
private String homeDir = new String();
public void setConfig(String quorum, Integer port,String parent,String homeDir) {
this.homeDir = homeDir;
this.quorum = quorum;
this.port = port;
this.parent = parent;
}
public Configuration configuration() {
System.setProperty("hadoop.home.dir", homeDir);
LOGGER.info("Hadoop Home Dir: {}, quorum: {}, port: {}", homeDir, quorum, port);
Configuration configuration = org.apache.hadoop.hbase.HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", quorum);// ip of hbase server(remote)
configuration.setInt("hbase.zookeeper.property.clientPort", port);// port: 2181 default
configuration.set("zookeeper.znode.parent", parent);
return configuration;
}
public Admin admin() {
Admin admin = null;
try {
Connection connection = ConnectionFactory.createConnection(configuration());
admin = connection.getAdmin();
} catch (IOException e) {
LOGGER.error("Init HBase Client Error.", e);
}
return admin;
}
public String getQuorum() {
return quorum;
}
public void setQuorum(String quorum) {
this.quorum = quorum;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getHomeDir() {
return homeDir;
}
public void setHomeDir(String homeDir) {
this.homeDir = homeDir;
}
}
3.2、HBase操作
封装 HBaseUtils.java 工具类,实现创建表、插入、读取、删除数据:
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.PropKit;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
public class HbaseUtils implements Serializable {
public static final Logger LOGGER = LoggerFactory.getLogger(HbaseUtils.class);
protected static final long serialVersionUID = 1L;
private static Admin hbaseAdmin = null;
static {
try {
Init();
} catch (Exception e) {
System.out.println(">----Hbase Init Failure ----");
e.printStackTrace();
}
}
public static void Init() {
System.out.println(">----Hbase Init Start ----");
PropKit.use("config.properties");
HBaseConfigInit hBaseConfigInit = new HBaseConfigInit();
hBaseConfigInit.setConfig(PropKit.get("hbase.addresses"), PropKit.getInt("hbase.port"),
PropKit.get("hbase.zookeeper.parent"),
PropKit.get("hadoop.home.dir"));
hbaseAdmin = hBaseConfigInit.admin();
System.out.println(">----Hbase Init Success----");
}
public static void main(String[] args) {
HbaseUtils hData = new HbaseUtils();
String tableName = "hbase_data";
hData.dropTable(tableName);
List<String> columnFamily = new ArrayList<>();
columnFamily.add("data");
hData.createTable(tableName,columnFamily);
}
/**
* 判断表是否存在
*
* @param tableName 表名
* @return true/false
*/
public static boolean isExists(String tableName) {
boolean tableExists = false;
try {
TableName table = TableName.valueOf(tableName);
tableExists = hbaseAdmin.tableExists(table);
} catch (IOException e) {
e.printStackTrace();
}
return tableExists;
}
/**
* 创建表
*
* @param tableName 表名
* @param columnFamily 列族
* @return true/false
*/
public boolean createTable(String tableName, List<String> columnFamily) {
if (!isExists(tableName)) {
try {
TableName table = TableName.valueOf(tableName);
TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(table);
for (String cf : columnFamily) {
builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(cf));
}
hbaseAdmin.createTable(builder.build());
return true;
} catch (IOException e) {
LOGGER.warn("HBase Create Table Error.", e);
}
} else {
LOGGER.warn("HBase Create Table Error. Table-{} already Exists", tableName);
}
return false;
}
/**
* 预分区创建表
*
* @param tableName 表名
* @param columnFamily 列族
* @param keys 分区集合
* @return true/false
*/
public boolean createTable(String tableName, List<String> columnFamily, List<String> keys) {
if (!isExists(tableName)) {
try {
TableName table = TableName.valueOf(tableName);
HTableDescriptor desc = new HTableDescriptor(table);
for (String cf : columnFamily) {
desc.addFamily(new HColumnDescriptor(cf));
}
if (keys == null) {
hbaseAdmin.createTable(desc);
} else {
byte[][] splitKeys = getSplitKeys(keys);
hbaseAdmin.createTable(desc, splitKeys);
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println(tableName + "is exists!!!");
return false;
}
return false;
}
/**
* 删除表
*
* @param tableName 表名
*/
public static void dropTable(String tableName) {
if (isExists(tableName)) {
TableName table = TableName.valueOf(tableName);
try {
hbaseAdmin.disableTable(table);
hbaseAdmin.deleteTable(table);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 插入(覆盖)数据
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
* @param data 数据键值对
* @return true/false 插入成功/失败
*/
public static boolean putData(String tableName, String rowKey, String columnFamily, Map<String, String> data) {
TableName tableNameObj = TableName.valueOf(tableName);
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj)) {
Put put = new Put(Bytes.toBytes(rowKey));
byte[] cf = Bytes.toBytes(columnFamily);
for (Map.Entry<String, String> entry : data.entrySet()) {
put.addColumn(cf, Bytes.toBytes(entry.getKey()), Bytes.toBytes(entry.getValue()));
}
table.put(put);
return true;
} catch (IOException e) {
LOGGER.warn("HBase Put Data Error.", e);
return false;
}
}
/**
* 插入数据(单条)
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
* @param column 列
* @param value 值
* @return true/false
*/
public boolean putData(String tableName, String rowKey, String columnFamily, String column,
String value) {
return putData(tableName, rowKey, columnFamily, Arrays.asList(column),
Arrays.asList(value));
}
/**
* 插入数据(批量)
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
* @param columns 列
* @param values 值
* @return true/false
*/
public boolean putData(String tableName, String rowKey, String columnFamily,
List<String> columns, List<String> values) {
try {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowKey));
for (int i = 0; i < columns.size(); i++) {
put.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columns.get(i)),
Bytes.toBytes(values.get(i)));
}
table.put(put);
table.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 获取数据(全表数据)
*
* @param tableName 表名
* @return map
*/
public List<JSONObject> getData(String tableName) {
List<JSONObject> results = new ArrayList<>();
try {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
ResultScanner resultScanner = table.getScanner(scan);
for (Result result : resultScanner) {
JSONObject json = cellToJSON(result);
results.add(json);
}
table.close();
} catch (IOException e) {
e.printStackTrace();
}
return results;
}
/**
* 获取数据(根据传入的filter)
*
* @param tableName 表名
* @param filter 过滤器
* @return List<JSONObject>
*/
public static List<JSONObject> getData(String tableName, Filter filter) {
List<JSONObject> results = new ArrayList<>();
try {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Scan scan = new Scan();
// 添加过滤器
scan.setFilter(filter);
scan.setLimit(100);
ResultScanner resultScanner = table.getScanner(scan);
for (Result result : resultScanner) {
JSONObject json = cellToJSON(result);
results.add(json);
}
table.close();
} catch (IOException e) {
e.printStackTrace();
}
return results;
}
/**
* 获取数据(根据rowkey,列族,列)
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
* @param columnQualifier 列
* @return map
*/
public String getData(String tableName, String rowKey, String columnFamily,
String columnQualifier) {
String data = "";
try {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnQualifier));
Result result = table.get(get);
if (result != null && !result.isEmpty()) {
Cell cell = result.listCells().get(0);
data = Bytes.toString(cell.getValueArray(), cell.getValueOffset(),
cell.getValueLength());
}
table.close();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
/**
* 删除数据(根据rowkey)
*
* @param tableName 表名
* @param rowKey rowKey
*/
public void deleteData(String tableName, String rowKey) throws IOException {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
table.delete(delete);
table.close();
}
/**
* 删除数据(根据rowkey,列族)
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
*/
public void deleteData(String tableName, String rowKey, String columnFamily)
throws IOException {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
delete.addFamily(columnFamily.getBytes());
table.delete(delete);
table.close();
}
/**
* 删除数据(根据rowkey,列族)
*
* @param tableName 表名
* @param rowKey rowKey
* @param columnFamily 列族
* @param column 列
*/
public void deleteData(String tableName, String rowKey, String columnFamily, String column)
throws IOException {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
delete.addColumn(columnFamily.getBytes(), column.getBytes());
table.delete(delete);
table.close();
}
/**
* 删除数据(多行)
*
* @param tableName 表名
* @param rowKeys rowKey集合
*/
public void deleteData(String tableName, List<String> rowKeys) throws IOException {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
List<Delete> deleteList = new ArrayList<>();
for (String row : rowKeys) {
Delete delete = new Delete(Bytes.toBytes(row));
deleteList.add(delete);
}
table.delete(deleteList);
table.close();
}
/**
* 分区【10, 20, 30】 -> ( ,10] (10,20] (20,30] (30, )
*
* @param keys 分区集合[10, 20, 30]
* @return byte二维数组
*/
private byte[][] getSplitKeys(List<String> keys) {
byte[][] splitKeys = new byte[keys.size()][];
TreeSet<byte[]> rows = new TreeSet<>(Bytes.BYTES_COMPARATOR);
for (String key : keys) {
rows.add(Bytes.toBytes(key));
}
int i = 0;
for (byte[] row : rows) {
splitKeys[i] = row;
i++;
}
return splitKeys;
}
private byte[] valueToBytes(Object val) {
if (val == null) {
return null;
}
Class<?> type = val.getClass();
if (type == Integer.class) {
return Bytes.toBytes((Integer) val);
} else if (type == BigDecimal.class) {
return Bytes.toBytes((BigDecimal) val);
} else if (type == Boolean.class) {
return Bytes.toBytes((Boolean) val);
} else if (type == Double.class) {
return Bytes.toBytes((Double) val);
} else if (type == Float.class) {
return Bytes.toBytes((Float) val);
} else if (type == Long.class) {
return Bytes.toBytes((Long) val);
} else if (type == Short.class) {
return Bytes.toBytes((Short) val);
} else if (type == String.class) {
return Bytes.toBytes((String) val);
} else {
return Bytes.toBytes(val.toString());
}
}
/**
* 获取最新
*
* @param tableName 表名
*/
public static List<JSONObject> scanNewestOne(String tableName) {
List<JSONObject> results = new ArrayList<>();
TableName tableNameObj = TableName.valueOf(tableName);
Scan scan = new Scan();
scan.setLimit(1);
scan.setReversed(true);
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj);
ResultScanner resultScanner = table.getScanner(scan)) {
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
results.add(json);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 获取全表数据
*
* @param tableName 表名
*/
public static List<JSONObject> scanAll(String tableName) {
List<JSONObject> results = new ArrayList<>();
TableName tableNameObj = TableName.valueOf(tableName);
Scan scan = new Scan();
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj);
ResultScanner resultScanner = table.getScanner(scan)) {
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
results.add(json);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 获取全表数据
*
* @param tableName 表名
*/
public static List<JSONObject> scanByFilter(String tableName, Filter filter) {
List<JSONObject> results = new ArrayList<>();
TableName tableNameObj = TableName.valueOf(tableName);
Scan scan = new Scan();
scan.setReversed(true);
// 添加过滤器
scan.setFilter(filter);
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj);
ResultScanner resultScanner = table.getScanner(scan)) {
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
results.add(json);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 获取全表数据
*
* @param tableName 表名
*/
public static List<JSONObject> scanByScan(String tableName, Scan scan) {
List<JSONObject> results = new ArrayList<>();
TableName tableNameObj = TableName.valueOf(tableName);
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj);
ResultScanner resultScanner = table.getScanner(scan)) {
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
results.add(json);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 一页页获取全表数据
*
* @param tableName 表名
*/
public static List<JSONObject> scanByPage(String tableName, Scan scan, int limit) {
List<JSONObject> results = new ArrayList<>();
scan.setLimit(limit);
String startRowKey = "";
try {
TableName tableNameObj = TableName.valueOf(tableName);
Connection connection = hbaseAdmin.getConnection();
Table table = connection.getTable(tableNameObj);
while (true) {
System.out.println(scan.toJSON());
ResultScanner resultScanner = table.getScanner(scan);
List<JSONObject> subResults = new ArrayList<>();
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
subResults.add(json);
}
}
LOGGER.info("HBase Get Data:" + subResults.size());
results.addAll(subResults);
if (subResults.size() < limit || subResults.size() == 0) {
break;
} else {
if (subResults.size() > 0)
startRowKey = subResults.get(subResults.size() - 1).getString("rowKey");
scan.withStartRow(startRowKey.getBytes(), false);
scan.setLimit(limit);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 获取全表数据
*
* @param tableName 表名
*/
public static List<JSONObject> scanByRowKeyPrefix(String tableName, String rowKeyPrefix, Integer limit) {
List<JSONObject> results = new ArrayList<>();
TableName tableNameObj = TableName.valueOf(tableName);
Scan scan = new Scan();
if (limit != null) {
scan.setLimit(limit);
}
scan.setReversed(true);
PrefixFilter prefixFilter = new PrefixFilter(rowKeyPrefix.getBytes());
scan.setFilter(prefixFilter);
Connection connection = hbaseAdmin.getConnection();
try (Table table = connection.getTable(tableNameObj);
ResultScanner resultScanner = table.getScanner(scan)) {
for (Result result : resultScanner) {
if (result != null && !result.isEmpty()) {
JSONObject json = cellToJSON(result);
results.add(json);
}
}
} catch (IOException e) {
LOGGER.warn("HBase Get Data Error. TableName: {}", tableName, e);
}
return results;
}
/**
* 获取数据(根据rowkey)
*
* @param tableName 表名
* @param rowKey rowKey
* @return map
*/
public static JSONObject getDataByRowKey(String tableName, String rowKey) {
JSONObject json = new JSONObject();
try {
Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
Result result = table.get(get);
if (result != null && !result.isEmpty()) {
json.putAll(cellToJSON(result));
}
table.close();
} catch (IOException e) {
e.printStackTrace();
}
return json;
}
private static JSONObject cellToJSON(Result result) {
JSONObject jsonObject = new JSONObject();
for (Cell cell : result.listCells()) {
if (!jsonObject.containsKey("rowKey")) {
String rowKey = Bytes.toString(cell.getRowArray(),
cell.getRowOffset(), cell.getRowLength());
jsonObject.put("rowKey", rowKey);
}
//列族
String family = Bytes.toString(cell.getFamilyArray(),
cell.getFamilyOffset(), cell.getFamilyLength());
//列
String qualifier = Bytes.toString(cell.getQualifierArray(),
cell.getQualifierOffset(), cell.getQualifierLength());
//值
String data = Bytes.toString(cell.getValueArray(),
cell.getValueOffset(), cell.getValueLength());
jsonObject.put(qualifier, data);
}
return jsonObject;
}
}
4、HBase常用的查看数据方式
4.1、基本介绍
HBase常用的查看数据方式有scan和get,get是一种特殊的scan,get是scan的startRow和endRow等于同一个值的特殊情况。
HBase的RowKey 是按照B+树的形式存放的,所以查找一个具体的RowKey 速度是非常快的,所以查询数据的时候一般都会设置scan的startRow和endRow,这样可以缩小查找的范围,所以RowKey 的设计在HBase里面是极为重要的。
可以这样讲,HBase里面的查询数据只有scan一种形式,就是在B+树里面查找RowKey ,而scan就是对RowKey 的一种顺序”扫”。
查看一下scan里面对RowKey的条件筛选,只有startRow和endRow这一组,所以可以理解为sql条件里面的”>”和”<”。
HBase的RowKey 是按照顺序排列的,所以在设计RowKey 的时候尽量将业务查询需要的字段设计到RowKey 里面,这样在查询的时候对RowKey 加上一定范围的限制。
Filter 可以在 scan的结果集基础之上,对返回的记录设置更多条件值,这些条件可与 RowKey 有关,可以与列名有关,也可以与列值有关,还可以将多个 Filter 条件组合在一起等等。基于Hbase本身提供的三维有序(主键有序、列有序、版本有序),这些 Filter 可以高效的完成查询过滤的任务。
注意:Filter 可能会导致查询响应时延变的不可控制。因为我们无法预测,为了找到一条符合条件的记录,背后需要扫描多少数据量,如果在有效限制了 Scan 范围区间(通过设置startRow 与stopRow 限制)的前提下,该问题能够得到有效的控制。
4.2、Scan类常用方法
1. 指定需要的family或column ,如果没有调用任何addFamily或Column,会返回所有的columns
scan.addFamily();
scan.addColumn();
2. 指定最大的版本个数。如果不带任何参数调用setMaxVersions,表示取所有的版本。如果不掉用setMaxVersions,只会取到最新的版本
scan.setMaxVersions();
3. 指定最大的时间戳和最小的时间戳,只有在此范围内的cell才能被获取
scan.setTimeRange();
4. 指定时间戳
scan.setTimeStamp();
5. 指定Filter来过滤掉不需要的信息
scan.setFilter();
6. 指定开始的行。如果不调用,则从表头开始
//scan.setStartRow();scan.withStartRow();
7. 指定结束的行(不含此行)
scan.setStopRow();//scan.withStopRow();
8. 指定最多返回的Cell数目,用于防止一行中有过多的数据,导致OutofMemory错误
scan.setBatch();9. 指定返回的family数目
scan.setLimit();
4.3、Filter 过滤操作
4.3.1、操作符(比较运算符)
要完成一个过滤的操作,至少需要两个参数。一个是如下抽象的操作符(比较运算符),Hbase 提供了枚举类型的变量来表示这些抽象的操作符:
- LESS:小于(即 <)
- LESS_OR_EQUAL:小于等于(即 <=)
- EQUAL:等于(即 =)
- NOT_EQUAL:不等于(即 <>)
- GREATER_OR_EQUAL:大于等于(即 >=)
- GREATER(即 >)
- NO_OP:排除所有
4.3.2、比较器(Comparator)
代表具体的比较逻辑,如果可以提高字节级的比较、字符串级的比较等:
- BinaryComparator 按字节索引顺序比较指定字节数组,采用 Bytes.compareTo(byte[])
- BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同
- NullComparator 判断给定的是否为空
- BitComparator 按位比较
- RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非 EQUAL
- SubstringComparator 判断提供的子串是否出现在 value 中
4.3.3、常见的过滤器
1.RowFilter
筛选出匹配的所有的行
Filter rf = new RowFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("row1"))); // OK 筛选出匹配的所有的行
2. PrefixFilter
筛选出具有特定前缀的行键的数据
Filter pf = new PrefixFilter(Bytes.toBytes("row")); // OK 筛选匹配行键的前缀成功的行
3. KeyOnlyFilter
只返回每行的行键,值全部为空
Filter kof = new KeyOnlyFilter(); // OK 返回所有的行,但值全是空
4. RandomRowFilter
本过滤器的作用就是按照一定的几率(<=0会过滤掉所有的行,>=1会包含所有的行)来返回随机的结果集,对于同样的数据集,多次使用同一个RandomRowFilter会返回不通的结果集,对于需要随机抽取一部分数据的应用场景,可以使用此过滤器:
Filter rrf = new RandomRowFilter((float) 0.8); // OK 随机选出一部分的行
5. InclusiveStopFilter
扫描的时候,我们可以设置一个开始行键和一个终止行键,默认情况下,这个行键的返回是前闭后开区间,即包含起始行,但不包含终止行,如果我们想要同时包含起始行和终止行,那么我们可以使用此过滤器:
Filter isf = new InclusiveStopFilter(Bytes.toBytes("row1")); // OK 包含了扫描的上限在结果之内
6. FirstKeyOnlyFilter
返回的结果集中只包含第一列的数据,它在找到每行的第一列之后会停止扫描,从而使扫描的性能也得到了一定的提升:
Filter fkof = new FirstKeyOnlyFilter(); // OK 筛选出第一个每个第一个单元格
7. ColumnPrefixFilter
按照列名的前缀来筛选单元格的
Filter cpf = new ColumnPrefixFilter(Bytes.toBytes("qual1")); // OK 筛选出前缀匹配的列
8. ValueFilter
按照具体的值来筛选单元格的过滤器,这会把一行中值不能满足的单元格过滤掉,如下面的构造器,对于每一行的一个列,如果其对应的值不包含ROW2_QUAL1,那么这个列就不会返回给客户端:
Filter vf = new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("ROW2_QUAL1")); // OK 筛选某个(值的条件满足的)特定的单元格
9. ColumnCountGetFilter
这个过滤器来返回每行最多返回多少列,并在遇到一行的列数超过我们所设置的限制值的时候,结束扫描操作:
Filter ccf = new ColumnCountGetFilter(2); // OK 如果突然发现一行中的列数超过设定的最大值时,整个扫描操作会停止
10. SingleColumnValueFilter
用一列的值决定这一行的数据是否被过滤。在它的具体对象上,可以调用setFilterIfMissing(true)或者setFilterIfMissing(false),默认的值是false,其作用是:对于要使用作为条件的列,如果这一行不包含指定的列,那么如果为true,这样的行将会被过滤掉,如果为false,这样的行会包含在结果集中。
SingleColumnValueFilter scvf = new SingleColumnValueFilter(
Bytes.toBytes("colfam1"),
Bytes.toBytes("qual2"),
CompareOperator.NOT_EQUAL,
new SubstringComparator("BOGUS"));
scvf.setFilterIfMissing(false);
scvf.setLatestVersionOnly(true); // OK
11. SingleColumnValueExcludeFilter
这个与SingleColumnValueFilter过滤器唯一的区别就是,作为筛选条件的列的不会包含在返回的结果中。
12. SkipFilter
这是一种附加过滤器,其与ValueFilter结合使用,如果发现一行中的某一列不符合条件,那么整行就会被过滤掉:
Filter skf = new SkipFilter(vf); // OK 发现某一行中的一列需要过滤时,整个行就会被过滤掉
13. WhileMatchFilter
这个过滤器的应用场景也很简单,如果你想要在遇到某种条件数据之前的数据时,就可以使用这个过滤器;当遇到不符合设定条件的数据的时候,整个扫描也就结束了:
Filter wmf = new WhileMatchFilter(rf); // OK 类似于Python itertools中的takewhile
14. FilterList
用于综合使用多个过滤器。其有两种关系:FilterList.Operator.MUST_PASS_ONE和FilterList.Operator.MUST_PASS_ALL,默认的是FilterList.Operator.MUST_PASS_ALL,顾名思义,它们分别是AND和OR的关系,并且FilterList可以嵌套使用FilterList,使我们能够表达更多的需求:
List<Filter> filters = new ArrayList<Filter>();
filters.add(rf);
filters.add(vf);
FilterList fl = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters); // OK 综合使用多个过滤器, AND 和 OR 两种关系