描述问题
添加测试数据
清空表:
truncate 'book'
添加数据:
put 'book','1001','c1:title','htlm从入门到放弃'
put 'book','1001','c1:author','lucy'
put 'book','1002','c1:title','css从入门到放弃'
put 'book','1002','c1:author','lili'
put 'book','1002','c1:price','099.90'
put 'book','1003','c1:title','hadoop从入门到放弃'
put 'book','1003','c1:author','韩梅梅'
put 'book','1003','c1:price','190.00'
put 'book','1003','c1:title','hbase从入门到精通'
put 'book','1003','c1:author','李雷'
put 'book','1003','c1:price','029.50'
注意: rowkey 是 1001 的记录,没有 price
代码
上接:hbase2.1.x java SingleColumnValueFilter 过滤
测试1:
hu.filter("book", "c1", "price",
CompareOperator.EQUAL,
"099.90");
查询结果:
1001 c1:author:lucy
c1:title:htlm从入门到放弃
------------------
1002 c1:author:lili
c1:price:099.90
c1:title:css从入门到放弃
原因:因为 rowkey 是 1001 的记录 没有 age ,在 hbase 中,默认 满足所有过滤条件
测试2:
列名写错了,写成大写的 PRICE
hu.filter("book", "c1", "PRICE",
CompareOperator.EQUAL,
"099.90");
查询出所有结果
原因:在 hbase 中,默认 满足所有过滤条件
解决
关键代码
filter.setFilterIfMissing(true);
解释:当 过滤条件的列 的 值为空 时,不满足条件,即:不包含该条记录
完整代码
/**
* 没有列值,认为不满足查询条件
* @param tableName
* @param columnFamily
* @param column
* @param op
* @param value
* @return
* @throws IOException
*/
public List<CellData[]> filter(String tableName, String columnFamily, String column, String op, String value) throws IOException {
return filter(tableName, columnFamily, column, op, value,true);
}
/**
*
* @param tableName 表名
* @param columnFamily 列族名
* @param column 列名
* @param op 操作,=,>,>=,<,<=,!=
* @param value 值
* @param filterIfMissing 设置为true,没有列值,认为不满足条件;false,没有列值,也满足条件
* @throws IOException
*/
public List<CellData[]> filter(String tableName, String columnFamily, String column, String op, String value,boolean filterIfMissing) throws IOException {
Table table = conn.getTable(TableName.valueOf(tableName));
//创建Scan
Scan scan=new Scan();
SingleColumnValueFilter filter=new SingleColumnValueFilter(
Bytes.toBytes(columnFamily),
Bytes.toBytes(column),
getCompareOperator(op),
new BinaryComparator(Bytes.toBytes(value))); // 注意是字符串
filter.setFilterIfMissing(filterIfMissing);
//传入filter
scan.setFilter(filter);
//执行scan
ResultScanner resultScanner = table.getScanner(scan);
Iterator<Result> iterator = resultScanner.iterator();
List<CellData[]> retList = new ArrayList<>();
//迭代,在迭代时,ResultScanner会发送get请求
while(iterator.hasNext()){
Result result=iterator.next();
//获取rowkey
String rowkey=Bytes.toString(result.getRow());
// System.out.print(rowkey+"\t");
//获取所有单元格
List<Cell> list=result.listCells();
CellData[] arr = new CellData[list.size()];
int i = 0;
for(Cell item:list){
String family=Bytes.toString(CellUtil.cloneFamily(item));
String qualifier=Bytes.toString(CellUtil.cloneQualifier(item));
String valueDb=Bytes.toString(CellUtil.cloneValue(item));
CellData cellData = new CellData(family,qualifier,rowkey,item.getTimestamp(),valueDb);
arr[i] = cellData ;
i ++ ;
}
retList.add(arr);
}
//用完要及时关闭,在迭代时,ResultScanner会发送get请求
resultScanner.close();
table.close();
return retList;
}
// 传入 =,>,>=,<,<=,!=,返回相对应的 CompareOperator
CompareOperator getCompareOperator(String op){
CompareOperator co = null;
switch (op) {
case "=":
co = CompareOperator.EQUAL;
break;
case ">":
co = CompareOperator.GREATER;
break;
case ">=":
co = CompareOperator.GREATER_OR_EQUAL;
break;
case "<":
co = CompareOperator.LESS;
break;
case "<=":
co = CompareOperator.LESS_OR_EQUAL;
break;
case "!=":
co = CompareOperator.NOT_EQUAL;
break;
default:
co = CompareOperator.NO_OP;
}
return co;
}
测试1
public static void main(String[] args) throws IOException {
HbaseUtils2_filter_ok utils=new HbaseUtils2_filter_ok();
utils.connect();
// 查询 price 小于等于 099.90的数据
List<CellData[]> resList = utils.filter("book", "c1", "price", "<=", "099.90");
// List<CellData[]> resList = utils.filter("book", "c1", "price", "<=", "099.90",false);
for(CellData[] arr : resList){
for(CellData item : arr){
// System.out.println(item.getFamily()+":"+item.getQualifier()+"-"+item.getTimestamp()+" == "+item.getValue());
System.out.print(item.getFamily()+":"+item.getRowkey()+":"+item.getQualifier() +" == "+item.getValue()+"\t\t");
}
System.out.println("----------");
}
utils.close();
}
正确