hbase2.1.x java SingleColumnValueFilter 列不存在时,无法过滤,满足所有过滤条件

描述问题

添加测试数据

清空表:

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

正确