Query HBase table by key using RowFilter not worki

2019-05-31 07:57发布

问题:

I have a HBase table (from java) and i want to query the table by list of keys. I did the following, but its not working.

mFilterFeatureIt = mFeatureSet.iterator();
FilterList filterList=new FilterList(FilterList.Operator.MUST_PASS_ONE);

while (mFilterFeatureIt.hasNext()) {
    long myfeatureId = mFilterFeatureIt.next();
System.out.println("FeatureId:"+myfeatureId+" , ");
RowFilter filter = new RowFilter(CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes(myfeatureId)) );
filterList.addFilter(filter);
}

outputMap  = HbaseUtils.getHbaseData("mytable", filterList);
System.out.println("Size of outputMap map:"+ outputMap.szie());

public static Map<String, Map<String, String>> getHbaseData(String table, FilterList filter) {

    Map<String, Map<String, String>> data = new HashMap<String, Map<String, String>>();
HTable htable = null;
try {
    htable = new HTable(HTableConfiguration.getHTableConfiguration(),table);
    Scan scan = new Scan();
    scan.setFilter(filter);

    ResultScanner resultScanner = htable.getScanner(scan);
    Iterator<Result> results = resultScanner.iterator();

    while (results.hasNext()) {

    Result result = results.next();
    String rowId = Bytes.toString(result.getRow());
    List<KeyValue> columns = result.list();
    if (null != columns) {

    HashMap<String, String> colData = new HashMap<String, String>();
    for (KeyValue column : columns) {
        colData.put(Bytes.toString(column.getFamily()) + ":"+ Bytes.toString(column.getQualifier()),Bytes.toString(column.getValue()));
    }
                data.put(rowId, colData);
    }

    }

    } catch (IOException e) {
    e.printStackTrace();
    } finally {
        if (htable != null)
    try {
    htable.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    return data;
}

FeatureId:80515900 , FeatureId:80515901 , FeatureId:80515902 ,

Size of outputMap map: 0

I see that value of feature id is what i want , but I always get the above output even if the key is present in the hbase table. Can anyone tell me what am i doing wrong ?

EDIT: I posted the code for my hbase util method too above, so that you can point me to any bugs there.

I am trying to do an SQL equivalent of select * FROM mytable where featureId in (80515900, 80515901, 80515902) My idea to achieve the same in HBase was to create a filter list with one filter for each featureId. Is that correct ?

Here is the content of my table

scan 'mytable', {COLUMNS => ['sample:tag_count'] }

80515900                                            column=sample:tag_count, timestamp=1339304052748, value=4                                                                                                
80515901                                            column=sample:tag_count, timestamp=1339304052748, value=0                                                                                                
80515902                                            column=sample:tag_count, timestamp=1339304052748, value=3       
80515903                                            column=sample:tag_count, timestamp=1339304052748, value=1                                                                                                
80515904                                            column=sample:tag_count, timestamp=1339304052748, value=2                                                                                                

回答1:

Its not returning any data as while inserting the data into hbase,
the data-type for key is 'String' (from your scan result) & while fetching, the value passed in RowFilter has 'long' data type. Use this filter:

RowFilter filter = new RowFilter(CompareOp.EQUAL,new    
BinaryComparator(Bytes.toBytes(myfeatureId.toString())) );


回答2:

the while loop will always generate a new filter and added to the filter list.

The circuit are all the keys in the filter. This filter can never apply to a single row. Create only one filter in the while loop pointing to a knowing "myfeatureId".

while (mFilterFeatureIt.hasNext()) {
    long myfeatureId = mFilterFeatureIt.next();
System.out.println("FeatureId:"+myfeatureId+" , ");
if ( myfeatureId=="80515902") {
     RowFilter filter = new RowFilter(CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes(myfeatureId)) );
     filterList.addFilter(filter);
     }
}

EDIT

For rows quantity, the query is responsible. HBase is not

HBase filters

Filters push row selection criteria out to the HBase. Rows can be filtered remotely and in parallel. Using these functions helps you to avoid sending rows to the client that are not needed.

To get a part out of the key, gets all from 80515900 .. 80515909 try this

of course remove from the loop

RowFilter filter = new RowFilter(CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes(myfeatureId)) );
filterList.addFilter(filter);

and add above the line outputMap = HbaseUtils.getHbaseData("mytable", filterList);

....
RowFilter filter = new RowFilter(CompareOp.EQUAL,new SubStringComparator("8051590"));
filterList.addFilter(filter);
outputMap  = HbaseUtils.getHbaseData("mytable", filterList);


标签: java hbase