2012-12-24 44 views
1

我有一個HBase的表,其中所有的鍵具有以下結構ID,日期,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); 

回答

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; 
} 
+0

非常好,謝謝:-)!是的,我實現getNextKeyHint()聽起來很複雜。你以前做過這樣的事情嗎?你可以嘗試爲我的用例創建一個例子嗎? – Julias

+0

我更新了答案添加了過濾器的近似實現。 –

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 
} 
+0

嗨,我不認爲我理解你的答案。我想查找比某個日期更早的所有行(日期在給定日期內)。你能寫一個代碼片段嗎? – Julias