Java 如何有效地为扫描器写入带有时间戳的行过滤器
我有一个hbase表,其中所有键都有以下结构ID、日期和其他详细信息 例如:Java 如何有效地为扫描器写入带有时间戳的行过滤器,java,hbase,Java,Hbase,我有一个hbase表,其中所有键都有以下结构ID、日期和其他详细信息 例如: 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
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);
将第一行的密钥存储在某个位置。它将始终存在于最终结果集中,是“第一”行,这使得它比所有其他行都旧(我说的对吗??) 现在获取日期,您希望使用该日期筛选出结果,并使用该日期创建带有RegexStringComparator的RowFilter。这将提供与指定条件匹配的行。现在,使用这一行和前面存储的第一行执行范围查询 如果有多行具有相同的日期,请说:
10,2012-05-04,"some details"
10,2012-05-04,"some new details"
取RowFilter之后的最后一行,并使用相同的技术
嗯
我想说的是,您可以使用范围查询来实现这一点。其中“startrowkey”将是您表格的第一行。作为第一行,它将始终是最早的一行,这意味着您的结果中将始终包含这一行。范围查询的“stoprowkey”将是包含给定日期的行。要查找stoprowkey,可以使用“RegexStringComparator”设置“RowFilter”
您可以创建自己的方法并实现该方法。为了使扫描速度更快,您也可以实现该方法,但这有点复杂。这种方法的缺点是需要将带有过滤器的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;
}
@覆盖
公共无效重置(){
this.filterOutRow=false;
}
@凌驾
public Filter.ReturnCode filterKeyValue(KeyValue v){
如果(此.filterOutRow){
使用提示返回ReturnCode.SEEK\u NEXT\u;
}
return Filter.ReturnCode.INCLUDE;
}
@凌驾
公共布尔filterRowKey(字节[]数据,整数偏移量,整数长度){
如果(开始日期<获取日期(数据)和结束日期>获取日期(数据)){
this.filterOutRow=true;
}
返回此.filterOutRow;
}
@凌驾
public KeyValue getNextKeyHint(KeyValue currentKV){
如果(getDate(currentKV)endDate){
字符串nextKey=(getId(currentKV)+1)+“,”+startDate.getTime();
返回KeyValue.createFirstOnRow(Bytes.toBytes(nextKey));
}
返回null;
}
@凌驾
公共布尔filterRow(){
返回此.filterOutRow;
}
嗨,我想我不明白你的答案。我想查找比某个日期早的所有行(其中日期在<给定日期)中。你能写一段代码吗?非常好,谢谢:-)!是的,对我来说实现getNextKeyHint()听起来很复杂。你以前做过这样的事吗?你能试着为我的用例创建一个例子吗?我更新了答案,添加了过滤器的近似实现。
@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;
}