1

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

2 回答 2

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;
}
于 2012-12-25T07:35:42.313 回答
0

将第一行的密钥存储在某处。它会始终存在于您的最终结果集中,作为“第一”行,这使得它比所有其他行都旧(我正确吗??)

现在获取日期,您要使用它来过滤结果并使用该日期创建一个带有 RegexStringComparator 的 RowFilter。这将给出匹配指定条件的行。现在,使用您之前存储的这一行和第一行进行范围查询。

如果您有多行具有相同的日期,请说:

10,2012-05-04,"some details"
10,2012-05-04,"some new details"

取最后一行,你会在 RowFilter 之后得到,并使用相同的技术。

高温高压

我想说你可以使用范围查询来实现这一点。其中“startrowkey”将是表格的第一行。作为第一行,它将始终是最旧的行,这意味着您的结果中将始终包含这一行。范围查询的“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
}
于 2012-12-24T20:54:28.343 回答