我有一个hbase表,其中所有键都具有以下结构ID,DATE,OTHER_DETAILS 例如:
10,2012-05-01,"some details"
10,2012-05-02,"some details"
10,2012-05-03,"some details"
10,2012-05-04,"some details"
...
如何编写扫描以获取比某个日期更早的所有行? 例如,2012-05-01和2012-05-02早于2012-05-03。
Scan scan = new Scan();
Filter f = ???
scan.setFilter(f);
scan.setCaching(1000);
ResultScanner rs = table.getScanner(scan);
答案 0 :(得分:2)
您可以创建自己的Filter并实施方法filterRowKey。为了使扫描更快,您还可以实现方法getNextKeyHint,但这有点复杂。这种方法的缺点是需要将带有过滤器的jar文件放入HBase类路径并重新启动集群。
此过滤器的近似实现。
@Override
public void reset() {
this.filterOutRow = false;
}
@Override
public Filter.ReturnCode filterKeyValue(KeyValue v) {
if(this.filterOutRow) {
return ReturnCode.SEEK_NEXT_USING_HINT;
}
return Filter.ReturnCode.INCLUDE;
}
@Override
public boolean filterRowKey(byte[] data, int offset, int length) {
if(startDate < getDate(data) && endDate > getDate(data)) {
this.filterOutRow = true;
}
return this.filterOutRow;
}
@Override
public KeyValue getNextKeyHint(KeyValue currentKV) {
if(getDate(currentKV) < startDate){
String nextKey = getId(currentKV)+","+startDate.getTime();
return KeyValue.createFirstOnRow(Bytes.toBytes(nextKey));
}
if(getDate(currentKV) > endDate){
String nextKey = (getId(currentKV)+1)+","+startDate.getTime();
return KeyValue.createFirstOnRow(Bytes.toBytes(nextKey));
}
return null;
}
@Override
public boolean filterRow() {
return this.filterOutRow;
}
答案 1 :(得分:0)
将第一行的密钥存储在某个地方。它将永远存在于你的最终结果集中,成为'第一行',这使得它比所有其他行更老(我是否正确?)
现在使用日期,您要使用该日期来过滤掉结果,并使用此日期使用RegexStringComparator创建RowFilter。这将给出符合指定条件的行。现在,使用此行和先前存储的第一行,执行范围查询。
如果您有多个具有相同日期的行,请说:
10,2012-05-04,"some details"
10,2012-05-04,"some new details"
取最后一行,你可以在RowFilter之后得到它,并使用相同的技术。
HTH
我试图说你可以使用范围查询来实现这一目标。其中“startrowkey”将是您表格的第一行。作为第一行,它总是最老的一行,这意味着你的结果中总会有这一行。并且范围查询的“stoprowkey”将是包含给定日期的行。要查找stoprowkey,您可以使用“RegexStringComparator”设置“RowFilter”。
byte[] startRowKey = FIRST_ROW_OF_THE_TABLE;
Scan scan = new Scan();
Filter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,new RegexStringComparator("YOUR_REGEX"));
scan.setFilter(filter);
ResultScanner scanner1 = table.getScanner(scan);
for (Result res : scanner1) {
byte[] stopRowKey = res.getRow();
}
scanner1.close();
scan.setStartRow(startRowKey);
scan.setStopRow(stopRowKey);
ResultScanner scanner2 = table.getScanner(scan);
for (Result res : scanner2) {
//you final result
}