Java 如何有效地为扫描器写入带有时间戳的行过滤器

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

我有一个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 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;
}